TypeError:'Logger'对象不可调用

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)) - 一切正常:

> 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>>
...
Run Code Online (Sandbox Code Playgroud)

但是 - 当class UnityXMLgenerator(RDSmanager)class AutoEnv(RDSmanager)方法调用时出现问题:

def mkconfig(self):
    ...
    confgen = UnityXMLgenerator()
    ...
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
Run Code Online (Sandbox Code Playgroud)

问题是:

  1. 为什么我办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()
  2. 究竟是什么意思" <logging.Logger object at 0x02534390>"和" <bound method Logger.logger of <lib.local.rds_services.Logger object at 0x032623D0>>"?
  3. 我在这里做错了什么,如何找到这个问题的解决方案?

Mar*_*ers 7

您有一个实例属性logger和一个名为的方法logger.你不能兼得:

def logger(self, modname):
    self.logger = logging.getLogger(modname)
Run Code Online (Sandbox Code Playgroud)

该实例属性logger使用相同的名称屏蔽该方法.使用其他名称.