- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
来自logging
howto对于 Python 2.7(我的重点):
A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows:
logger = logging.getLogger(__name__)
This means that logger names track the package/module hierarchy, and it’s intuitively obvious where events are logged just from the logger name.
听起来不错。
现在,logging
cookbook为多个模块提供了一个示例,它使用硬编码的记录器名称而不是 __name__
常量。在示例的“主模块”中,我们发现
logger = logging.getLogger('spam_application')
在我们发现的“辅助模块”中
module_logger = logging.getLogger('spam_application.auxiliary')
我将这个示例逐字复制到具有以下结构的包文件夹中:
cookbook-example
|- __init__.py
|- main_module.py
|- auxiliary_module.py
这运行没有问题,从主模块和辅助模块产生预期的日志输出,但事情是这样的:
如果我现在按照 logging
howto 的建议用 __name__
常量替换硬编码的记录器名称,食谱示例出现故障:我只从主模块获取日志消息,但没有从辅助模块获取日志消息。
我一定遗漏了一些明显的东西。知道我做错了什么吗?
注意:
有很多非常相似的问题和相关答案,例如:1 , 2 , 3 , 4 , 5 , 6 , 还有很多。但是,这些似乎都没有解决这个具体问题。
--编辑--
这是一个基于食谱示例的最小示例,其中显式名称字符串替换为 __name__
。
主模块.py
import logging
import auxiliary_module
# create and configure main logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# create console handler with a higher log level
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
# create formatter and add it to the handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# add the handler to the logger
logger.addHandler(handler)
logger.info('message from main module')
auxiliary_module.some_function()
auxiliary_module.py
import logging
# create logger
module_logger = logging.getLogger(__name__)
def some_function():
module_logger.info('message from auxiliary module')
最佳答案
正如@shmee 在 this answer 中指出的那样,必须使用点符号在记录器名称中明确定义记录器层次结构。也就是说,如果 main_module.py
中的记录器名称是例如'a'
,那么 auxiliary_module.py
中的记录器名称必须是 'a.b'
(不仅仅是 'b'
),以使其继承logger'a'
的配置。 getLogger()
documentation中也提到了这一点.
然而,这应该在使用 __name__
时自动处理,如 logging
how-to 中所述:
This means that logger names track the package/module hierarchy, and it’s intuitively obvious where events are logged just from the logger name.
问题是,要使其正常工作,您需要以正确的方式使用 __name__
,而我没有这样做。
我的示例中的问题在于 cookbook-example
包文件夹中文件的组织:
主模块和辅助模块都处于同一级别(即在同一文件夹中)。所以,正如解释的here ,主模块的 __name__
将是 '__main__'
(因为它是顶级脚本),而 __name__
辅助模块将是 'auxiliary_module'
(即文件名),而不是 '__main__.auxiliary_module'
。
因此,辅助模块中的记录器将是根记录器的子项,而不是 '__main__'
记录器的子项,因此它将继承根记录器配置(仍然具有默认日志记录级别 WARNING
) 而不是主模块中指定的配置。
因此,为了使示例正常运行,我们有多种选择:
将 main 模块中的 getLogger(__name__)
替换为 getLogger()
。这会将配置应用于根记录器,因此也应用于辅助模块记录器,正如@shmee 所建议的那样。
将 auxiliary 模块中的 getLogger(__name__)
替换为getLogger('__main__.' + __name__)
。结果将是等价的到原始的食谱示例(除了主记录器现在被称为'__main__'
而不是 'spam_application'
)。
关于python - 如何在多个模块中使用 logging.getLogger(__name__),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50714316/
在尝试执行类似于 ActiveState 配方中标题为 Constants in Python 的操作时通过 Alex Martelli,我遇到了意想不到的副作用(在 Python 2.7 中),将类
我正在尝试编写一个类来捕获任何通用函数调用,然后尝试使用它进行一些操作。 作为示例,我尝试使用 here 中类似问题的答案. 但是,当我尝试通过分配 __name__ 属性来更改方法的名称时,它会抛出
这个问题在这里已经有了答案: Why does cls.__name__ not appear in dir()? (4 个答案) 关闭 5 年前。 Class_object 的名称可以通过.__n
n = 20 print n.__name__ 我收到一个错误,因为 n 没有属性 __name__: AttributeError: 'int' object has no attribute '_
在 Python 中,您可以通过 __file__ 获取正在执行的文件的路径是否有等效的 java? 还有一种方法可以像 __name__ 一样获取你当前所在的包吗? 最后,Java 自省(intro
在 rootes.js 中 .state('main.mydata', { url: '/my-data', templateUrl: '/app/views/pages/my-dat
我尝试在网上寻找答案,但找不到。我对 python 相当陌生,想知道程序中是否可以有多个 main 函数。例如: ask_user = int(input('enter your choice (1
在我的 Python Shell 中,删除 __name__ 使其成为 'builtins'。虽然,检查 globals 确认我没有从某个全局变量中引用 __name__。 Python 3.6.2
__name__ 是做什么的?我只看到它与 __main__ 配对,没有其他。 我知道经典的 if __name__ == __main__: 定义了作为包运行与作为独立运行时的行为。 但是 __na
我正在通过阅读 Dive Into Python 来学习 Python在网上,在第 2 章中,我看到您可以使用 __name__ 属性进行测试,所以我想知道,是否有人知道此属性的其他用途?谢谢 最佳答
我正在尝试在我的应用程序中实现基于角色的权限。我有一个装饰器 role_required,我可以将一组用户角色传递到其中,只有具有该角色的用户才能访问该 View 。我已经为用户正确分配了角色,但是,
我正在使用 if __name__ == "__main__": 运行我定义的函数。 然而,作为一种错误捕获措施,我正在尝试实现一种方法来确保文件路径已正确输入到运行我的脚本的 .bat 文件中,文件
要获取类名的字符串表示,我们可以使用 obj.__class__.__name__是否可以重载这些方法以便我可以返回我的字符串而不是实际的类名? 最佳答案 让我们试试吧! (是的,这有效): >>>
为什么不能声明性地覆盖类名,例如使用不是有效标识符的类名? >>> class Potato: ... __name__ = 'not Potato' ... >>> Potato._
所以我有几个 Django 设置文件,一个用于测试,其他用于不同的客户。 这些设置文件都不会改变 sys.path。 所有这些都包含一个单一的基本设置文件,其中包含 INSTALLED_APPS。 大
为什么不能声明性地覆盖类名,例如使用不是有效标识符的类名? >>> class Potato: ... __name__ = 'not Potato' ... >>> Potato._
当我运行时: exec("print(__name__)") 它打印__main__。 但是当我运行时: exec("print __name__", {}) 它打印builtins。 如何让第二个例
给定以下设置: def mapper(f): def wrapper(items): for x in items: yield f(x) wr
我试图了解分配给 Python 类对象的变量与该类对象的 __name__ 属性之间的关系。例如: In [1]: class Foo(object): ...: pass ...
目录 1.程序入口 2.__name__是什么? 场景1:直接运行脚本 场景2:从其他脚本导入 3.__name__
我是一名优秀的程序员,十分优秀!