【问题标题】:Python: is there an equivalent to logging.getLogger(__name__) for argparse's parsers to pass args between modules?Python:argparse 的解析器是否有等效于 logging.getLogger(__name__) 在模块之间传递参数的方法?
【发布时间】:2020-07-22 17:16:24
【问题描述】:

日志库允许我们定义一个可以从任何导入的模块访问的全局记录器,如下所示:

main_script.py:

import logging
import module.py

if __name__ == "__main__":
    logging.config.fileConfig('/path/to/logging.conf')
    main(sys.argv[1:])

然后在module.py中:

import logging
logger = logging.getLogger(__name__)

这很好,因为这意味着无需在模块之间传递详细或调试标志。

我原以为 argparse 会存在等效的东西,例如允许在主脚本或单独的模块中进行解析,然后提供一种从任何其他模块访问它们的方法。毕竟,sys.argv 可以从任何模块访问,但是在每个模块中重新创建一个新的解析器只是为了访问它们似乎有些荒谬;另一种方法是在函数调用中传递 args。

我在这里遗漏了什么明显的东西吗?

提前致谢!

【问题讨论】:

  • argparse 相对简单且独立。正如您所注意到的,它访问sys.argv。否则它没有任何全局体现或钩子。通常parse_args() 是从if __name__=='__main__': 块调用的,所以它只被main 脚​​本使用,而不是被导入的模块使用。拥有多个活跃的解析器是自找麻烦。
  • 这也是我的观点,但我想避免在我的大多数模块中将 args 作为每个函数的第一个参数(这是它所采用的方向......)所以我想知道是否有其他被认为是最佳做法的替代方法。

标签: python logging module global argparse


【解决方案1】:

logging 在其模块命名空间中跟踪记录器。由于logging.logger 在该命名空间中运行,因此它很容易找到您想要的记录器。 argparse 不会这样做,但您可以在自己的模块中实现相同的功能。创建一个每个人都可以导入的模块,并让它为您解析参数。第一个调用触发参数解析,其他的只是得到结果。

myconfig.py

import sys
import argparse

args = None

def get_args(argv=sys.argv):
    global args
    if args is None:
        parser = argparse.ArgumentParser(description='Foo The Bar')
        # todo: add arguments…
        args = parser.parse_args(argv)
    return args

可能希望在主脚本处理的早期调用get_args,以防万一出现错误,或者调用者想要的只是--help

【讨论】:

  • 感谢您的回答!我一直环顾四周,不敢相信我是唯一一个遇到这个问题的人。既然我想到了,您的解决方案似乎非常漂亮和合乎逻辑!以这种方式访问​​ args 是否被认为是最佳实践?
  • 至于最佳实践......这是一个相当大的主题。这是我的看法 - 全局配置运行不利于可测试性。我更喜欢以较小的块编写我的程序,这些块可以用固定状态进行测试,然后将它们放在一个主目录中。 Main 将 argparse 但从实际程序的配置中构建更小的对象。但是(!)我从事过非常成功的项目,其中通过 argparse 提供的丰富的命令/子命令解析是一个核心功能。从某种意义上说,argparse 是主要的。所以我可以平等地争论双方。
猜你喜欢
  • 2018-11-15
  • 2016-04-22
  • 2020-03-18
  • 1970-01-01
  • 2015-02-06
  • 2021-10-20
  • 2011-05-05
  • 1970-01-01
相关资源
最近更新 更多