符合PEP8规范的整个包日志记录开关的方法

3

我有一个具有以下结构的包:

mypackage
    |
    +---- a.py
    +---- b.py
    +---- __init__.py

这个包有时被用作库,有时与IPython交互使用,因此我需要在两种情况下分别配置日志记录:

  • 与IPython交互:在控制台中打印日志,因此记录器应该有一个StreamHandler处理程序
  • 作为库:让用户配置日志记录,因此记录器应该有一个NullHandler处理程序

__init__.py文件中,我做了如下操作:

import logging
import a
import b

logging.getLogger(__name__).addHandler(logging.NullHandler())    

def get_loggers():
    """
    Get all the logger objects instantiated for the current package
    """
    loggers = []
    for logger in logging.Logger.manager.loggerDict.values():
        if not isinstance(logger, logging.Logger):
            continue
        if logger.name.startswith(__name__):
            loggers.append(logger)
    return loggers


def enable_logs():
    """
    Configure loggers to print on stdout/stderr
    """
    handler = logging.StreamHandler()
    handler.setFormatter(logging.Formatter(
        '%(name)s :: %(levelname)s :: %(message)s'))
    for logger in get_loggers():
        logger.removeHandler(handler)
        logger.addHandler(handler)
        logger.setLevel(logging.DEBUG)
        logger.propagate = False


def disable_logs():
    """
    Configure loggers not to print anywhere
    """
    handler = logging.NullHandler()
    for logger in get_loggers():
        logger.removeHandler(handler)
        logger.addHandler(handler)
        logger.propagate = False

a.pyb.py都以以下内容开始:

import logging

log = logging.getLogger(__name__)
log.addHandler(logging.NullHandler())

现在,我可以通过以下方式启用/禁用日志记录:

import mypackage
mypackage.enable_logs()
mypackage.disable_logs()

但这种解决方案不符合 PEP8,因为在__init__.py中导入了未使用的模块。请注意,不必导入它们,但我想这样做是因为当我导入包时,它们各自的日志记录器也会被创建。

问题1:有没有符合PEP8的方法来实现同样的目标?

问题2:这可能是主观的,但在这种情况下遵循PEP8值得吗?


1
我会遵循PEP20:尽管实用性胜过纯粹性。 - user3557327
PEP8在哪里明确说明了这是不允许的? - Simeon Visser
@SimeonVisser 实际上,pylint 正在说 W0611 'a' imported but unused。我以为这是 PEP8 的事情,但也许实际上并不是 =/ 我正在使用带有 python-mode 的 vim,这就是我从中获得错误的地方,顺便说一下。 - little-dude
更正:pyflakes 抛出了错误。实际上,这里有一个关于错误有效性的讨论 https://bugs.launchpad.net/pyflakes/+bug/1178905 - little-dude
1个回答

1
你可以在启用和禁用日志函数的开头调用此函数以动态加载模块,但我认为这样绕过PEP可能是作弊的。
import glob
import imp
import os

def load_modules(module_names=None):
    if module_names is None:
        cur_dir = os.path.realpath(os.path.dirname(__file__))
        module_wc = '{}/*.py'.format(cur_dir)
        module_names = [mn for mn in glob.glob(module_wc) if not mn.startswith('_')]
    modules = map(imp.load_source, module_names)
    return modules

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