我是Python的新手,尤其是在多个文件中编写模块和函数,而不仅仅是原始脚本。
我正在编写一个命令行应用程序,我想有一个函数(我称它为argpconf
),它将解析命令行参数并相应地设置日志级别。最重要的是,我希望在此功能中设置一次日志级别,并在创建其记录器时在所有模块中将其设置为最低开销。另外,我希望能够在使用通用格式化程序时识别出消息所来自的模块:
logging.Formatter("%(levelname)s : %(name)s : %(message)s")
部分基于a cookiecutter template,我创建了以下文件:
├── api
│ ├── __init__.py
│ └── some_functionality.py
├── cli.py
├── core
│ ├── argpconf.py
│ ├── __init__.py
│ ├── logger.py
│ └── __version__.py
├── __init__.py
└── __main__.py
core/logger.py
具有以下内容:
from logging import Formatter, Logger as _Logger, NullHandler, StreamHandler
class Logger(_Logger):
def __init__(self, name=None):
super(Logger, self).__init__(name or __name__.split(".")[0])
self.addHandler(NullHandler()) # default to no output
def start(self, level="WARN", stream=None,
fmt="%(levelname)s : %(name)s : %(message)s"):
handler = StreamHandler(stream)
handler.setFormatter(Formatter(fmt))
self.addHandler(handler)
self.setLevel(level.upper())
def stop(self):
for handler in self.handlers[1:]:
# Remove everything but the NullHandler.
self.removeHandler(handler)
logger = Logger()
与这些问题的答案中建议的想法相比:
我真的很喜欢记录程序在cookiecutter模板中采用的方法,因为它只允许您import logger
并拥有一个logger
对象,该对象的日志级别在所有模块中都是相同的。但是,我并不完全满意,因为在我的情况下,argpconf.py
是启动logger
的第一个模块,因此所有模块的所有日志消息都将其%(name)s
替换为{ {1}},因为它是core
的{{1}}。
如何改进argpconf.py
模块,使其能够检测到调用它的模块,并使用__name__.split(".")[0]
模块甚至打印它的功能来打印日志消息?
答案 0 :(得分:2)
这种方法似乎使事情变得比所需复杂。我意识到这来自您使用的cookiecutter模板,这只是我的观点,但是在该模板中进行日志记录的方法并不是我认为的最佳实践。您最了解用例,但是如果我想做的只是
有一个函数可以解析命令行参数并相应地设置日志级别。最重要的是,我希望在此功能中设置一次日志级别,并在创建其记录器时在所有模块中将其设置为最低开销。此外,我希望能够在使用通用格式化程序时识别出消息所来自的模块
然后,最简单的方法是在主脚本中导入argparse
和logging
,处理命令行参数并相应地设置日志记录级别,然后调用basicConfig()
(如Brian M中所建议。 Sheldon的注释),然后根据命令行参数将其分派到您的应用程序端点。您使用的每个需要记录某些内容的模块只需要先登录import logging
和logger = logging.getLogger(__name__)
,然后再登录logger.debug(...)
或任何其他内容,无论该模块中需要什么地方。如果坚持这一点,所有模块将自动使用basicConfig()
中设置的日志记录级别,如果您在%(name)s
的{{1}}参数中使用片段format=
,则您将会在记录的消息中的那个位置看到完整的模块名称,如全限定的点分名称(例如basicConfig()
)。这种方法肯定会比cookiecutter模板具有更少的创建记录器的开销。
更新:我将通过示例更新Python Logging Cookbook。现在,here's a Gist仅包含代码。