我有工具,其中使用了一些带继承的类。
这是我的第一个基于OOP的大工具,我对类初始化有点困惑。
下面的大量代码,使 Q 更清晰。
短继承树:
- RDSmanager(object)
- Options(RDSmanager)
- AutoEnv(RDSmanager)
- UnityXMLgenerator(RDSmanager)
完全记录器类是:
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)
主脚本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)
接下来,我在其他类中有两个选项 - -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()
接下来,每个类都运行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__)
使用-c
选项时(即 - class UnityXMLgenerator(RDSmanager)
直接从class Options(RDSmanager)
初始化) - 一切正常:
> 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()
...
并运行:
> 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)
初始化时{1}}的子类班AutoEnv(RDSmanager)
与confgen = UnityXMLgenerator()
?<logging.Logger object at 0x02534390>
”和“<bound method Logger.logger of <lib.local.rds_services.Logger object at 0x032623D0>>
”?答案 0 :(得分:7)
您同时拥有名为logger
的实例属性logger
和方法。你不能同时拥有:
def logger(self, modname):
self.logger = logging.getLogger(modname)
该实例属性logger
使用相同的名称屏蔽该方法。使用其他名称。