set*_*voy 2 python oop logging
我有工具,其中使用了一些继承的类.
这是我的第一个基于OOP的大工具,我对类初始化有点困惑.
下面有很多代码,使这个Q更加清晰.
短继承树:
- RDSmanager(object)
- Options(RDSmanager)
- AutoEnv(RDSmanager)
- UnityXMLgenerator(RDSmanager)
Run Code Online (Sandbox Code Playgroud)
完全记录器类是:
class Logger(object):
def __init__(self, rdsmanager_localpath):
"""Create Logger"""
self.rdsmanager_localpath = rdsmanager_localpath
if not os.path.isdir(os.path.join(self.rdsmanager_localpath, 'logs')):
os.mkdir(os.path.join(self.rdsmanager_localpath, 'logs'))
def logger(self, modname):
self.logger = logging.getLogger(modname)
formatter = logging.Formatter('%(asctime)s - %(filename)s[LINE:%(lineno)d] - %(name)s.%(funcName)s() - %(message)s')
self.logger.setLevel(logging.DEBUG)
filehandler = logging.FileHandler(os.path.join(self.rdsmanager_localpath, 'logs', 'rdsmanager.log'))
filehandler.setLevel(logging.DEBUG)
filehandler.setFormatter(formatter)
consolehandler = logging.StreamHandler()
consolehandler.setLevel(logging.INFO)
self.logger.addHandler(filehandler)
self.logger.addHandler(consolehandler)
Run Code Online (Sandbox Code Playgroud)
主脚本RDSmanager.py
包含:
from lib.local.rds_services import Logger
...
class RDSmanager(object):
...
# path to current RDSmanager directory
# used toi determine where files (generated XML, logs etc) c to store in
rdsmanager_localpath = os.path.dirname(os.path.abspath(__file__))
# global logger object
logger = Logger(rdsmanager_localpath)
Run Code Online (Sandbox Code Playgroud)
接下来,我有两个选择- -c
和-D
其他类:
class Options(RDSmanager):
"""Main "selector" for passed options.
For each option - appropriate Class.method() will be imported, initialized and called."""
def getopts(self):
...
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# Unity options
parser_unity = subparsers.add_parser('unity', help='Unity application options')
parser_unity.set_defaults(func=self.handler_unity)
...
parser_unity.add_argument('-c',
'--confgen',
action='store_true',dest='unity_confgen',
...
parser_unity.add_argument('-D',
'--deployauto',
action='store_true',
dest='unity_autoenv_deploy',
...
def handler_unity(self, options_list):
...
if options_list.unity_confgen:
self.logger.logger.info('Running Unity XML files generator.')
from lib.unity.xml_config_generator import UnityXMLgenerator
confgen = UnityXMLgenerator()
# generate application's config.xml
confgen.config_xml_generator()
# generate XML files for each module with TAG == 'CLOUD'
# see lib.unity.unity_services.UnityServices() docstring for details
confgen.modules_xmls_generator()
...
if options_list.unity_autoenv_deploy:
self.logger.logger.info('Running developers AutoEnvironment deploy.')
from lib.unity.autoenv.developers_auto_env import AutoEnv
auto = AutoEnv()
auto.deploy()
Run Code Online (Sandbox Code Playgroud)
接下来,每个类都运行logger
初始化,即:
class UnityXMLgenerator(RDSmanager):
def __init__(self):
print(id(self.logger.logger))
print(id(self.logger))
# self.build_type = build_type
# self.logger.logger(self.__class__.__name__)
print('self.logger')
print(self.logger)
print('self.logger.logger')
print(self.logger.logger)
self.logger.logger(self.__class__.__name__)
...
class AutoEnv(RDSmanager):
def __init__(self):
# self.build_type = build_type
self.logger.logger(self.__class__.__name__)
Run Code Online (Sandbox Code Playgroud)
当-c
使用选项时(即 - class UnityXMLgenerator(RDSmanager)
直接初始化时class Options(RDSmanager)
) - 一切正常:
Run Code Online (Sandbox Code Playgroud)> RDSmanager.py unity -c RDSmanager started at 23, Sep 2015 at 14:38:57 Running Unity XML files generator. 39816128 52831184 self.logger <lib.local.rds_services.Logger object at 0x032623D0> self.logger.logger <bound method Logger.logger of <lib.local.rds_services.Logger object at 0x032623D0>> ...
但是 - 当class UnityXMLgenerator(RDSmanager)
从class AutoEnv(RDSmanager)
方法调用时出现问题:
def mkconfig(self):
...
confgen = UnityXMLgenerator()
...
Run Code Online (Sandbox Code Playgroud)
并运行:
Run Code Online (Sandbox Code Playgroud)> RDSmanager.py unity -D RDSmanager started at 23, Sep 2015 at 14:43:16 Running developers AutoEnvironment deploy. Story NG-5859-developers-auto-env-build-config status checked - OK 39011216 52678608 self.logger <lib.local.rds_services.Logger object at 0x0323CFD0> self.logger.logger <logging.Logger object at 0x02534390> Traceback (most recent call last): File "D:\Dropbox\RDS\rdsmanager_NG-1\RDSmanager.py", line 258, in <module> rds.getopts() File "D:\Dropbox\RDS\rdsmanager_NG-1\RDSmanager.py", line 176, in getopts res.func(res) File "D:\Dropbox\RDS\rdsmanager_NG-1\RDSmanager.py", line 228, in handler_unity auto.deploy() File "D:\Dropbox\RDS\rdsmanager_NG-1\lib\unity\autoenv\developers_auto_env.py", line 95, in deploy self.mkconfig() File "D:\Dropbox\RDS\rdsmanager_NG-1\lib\unity\autoenv\developers_auto_env.py", line 70, in mkconfig confgen = UnityXMLgenerator() File "D:\Dropbox\RDS\rdsmanager_NG-1\lib\unity\xml_config_generator.py", line 32, in __init__ self.logger.logger(self.__class__.__name__) TypeError: 'Logger' object is not callable
问题是:
confgen = UnityXMLgenerator()
从class Options(RDSmanager)
-对象self.logger.logger
是" <bound method Logger.logger of <lib.local.rds_services.Logger object at 0x032623D0>>
" -但它是" <logging.Logger object at 0x02534390>
" -当它从初始化class RDSmanager(object)
的子类类AutoEnv(RDSmanager)
用confgen = UnityXMLgenerator()
?<logging.Logger object at 0x02534390>
"和" <bound method Logger.logger of <lib.local.rds_services.Logger object at 0x032623D0>>
"?您有一个实例属性logger
和一个名为的方法logger
.你不能兼得:
def logger(self, modname):
self.logger = logging.getLogger(modname)
Run Code Online (Sandbox Code Playgroud)
该实例属性logger
使用相同的名称屏蔽该方法.使用其他名称.