使用多个模块的Python日志记录无法正常工作

7
我创建了一些 Python 文件,将我的函数分开以便于工作和修复。所有文件都在一个目录中。结构可能会被分解成类似以下内容的内容:
  • a.py(一个包含基本内容的 A 类)
  • b.py(一个包含基本内容的 B 类)
  • modA.py(从 A 和 B 派生出一个 C 类)
  • modB.py(从 A 和 B 派生出一个 D 类)
  • ...
  • main_a.py(使用 C 类)
  • main_b.py(使用 D 类)
每个模块都使用 Python 的日志记录工具。不知何故 - 只有根记录器消息被写入。我看不到我的错误。
以下是一个最小化的示例。 a.py
import logging
logger = logging.getLogger(__name__)

class A(object):
    def __init__(self):
        logger.debug("Instance of A")

b.py

import logging
logger = logging.getLogger(__name__)

class B(object):
    def __init__(self):
        logger.debug("Instance of B")

ab.py

import a
import b
import logging
logger = logging.getLogger(__name__)

class AB(a.A, b.B):
    def __init__(self):
        logger.debug("Instance of AB")
        a.A.__init__(self)
        b.B.__init__(self)

main_one.py

import sys
import ab

import logging
import logging.handlers
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(stream=sys.stderr)
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter('%(name)s: %(message)s'))
logger.addHandler(handler)

logger.warning("The trouble starts")

ab = ab.AB()

我曾尝试使用类似 self.logger = logging.getLogger(type(self).__name__) 的方法来对每个类进行日志记录,但结果是一样的。所以你们中的某个人能指出我在阅读Python日志记录手册时哪里错了吗?
TIA.
编辑1:我的解决方案
感谢 @falsetru 和 @Jakub M.,使用这两个答案可以得到一个工作的解决方案。
首先,我把所有东西都放在一个层次结构中。
main_one.py
  lib/
    __init__.py
    ab.py
    basic/
      __init__.py
      a.py
      b.py

其次,我将 main_one.py 中的 logger = logging.getLogger(__name__) 更改为 logger = logging.getLogger()根记录器没有名称!)。

这样就解决了问题。

GitHub 上的代码片段非常有帮助。

2个回答

2

对于您的每个模块都执行print __name__,看看实际上会得到什么。您应该将您的模块放入适当的目录中,以便__name__是一个“分层值”。例如,如果您的文件层次结构如下:

main_a.py
libs/
  __init__.py
  a.py
  modA.py

那么你的模块(a.pymodA.py)的__name__将是libs.alibs.modA

名称可能是由句点分隔的分层值,例如foo.bar.baz(尽管它也可以只是简单的foo)。名称更深入层次结构列表中的记录器是名称更高的记录器的子级。例如,给定名称为foo的记录器,则具有名称为foo.bar、foo.bar.baz和foo.bam的记录器都是foo的后代。记录器名称层次结构类似于Python包层次结构,并且如果您使用建议的构造logging.getLogger(name)在每个模块上组织您的记录器,那么它与Python包层次结构相同。这是因为在模块中,name是Python包命名空间中模块的名称。


1

为所有模块使用相同的记录器名称。 __name__ 是模块名称; a, b, ab, main_one ...

logger = logging.getLogger('daniel_lib')

好的 - 这解决了工作基础上的问题,但仍然有一些疑问。据我所知,我失去了可移植性? - Daniel
@daniel 我不明白你所说的 失去可移植性 是什么意思。 - falsetru
我可以在所有模块中使用固定的记录器名称,但如果我使用这些模块,就必须始终使用此记录器名称吗? 这个 似乎是通过使用目录结构和配置完成的。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接