【问题标题】:Switch between hardcoded configuration and command line with argparse使用 argparse 在硬编码配置和命令行之间切换
【发布时间】:2017-12-27 13:08:04
【问题描述】:

为了便于开发,我在代码中使用了硬编码的 argparse 配置

import argparse

if __name__ == '__main__':
    local_conf = {
        "debug": True,
        "loglevel": 2
    }

    parser = argparse.ArgumentParser()
    parser.add_argument("--from_bash", action="store_true")
    parser.add_argument("--debug", action="store_true")
    parser.add_argument("--loglevel", default=5)
    conf =parser.parse_args()

    if not conf.from_bash:
        conf.__dict__ = {**conf.__dict__, **local_conf}  # merges configurations

    ....

我发现通过评论打开和关闭选项更容易。

要从脚本执行它,我使用一个选项告诉程序忽略硬编码配置:--from_bash 这里

python main.py --from_bash --loglevel 3

这很容易出错,如果我忘记了 --from_bash 选项,我会得到错误的配置。

有没有更简洁的方式在硬编码配置和命令行之间切换?

【问题讨论】:

  • 看起来您的用户需要从 3 个值中进行选择,local_confargparse 默认值和用户提供的值。你真的需要那些argparse 默认值吗?

标签: python configuration argparse


【解决方案1】:

这里有两种选择。


当用户希望他们的配置得到遵守时,您将精神负担添加到--from_bash。需要一个特殊标志可能更有意义,以便硬编码配置仅与标志一起使用。

...
parser = argparse.ArgumentParser()
parser.add_argument("--dev", action="store_true", help=argparse.SUPPRESS)  # Don't show in help message... user doesn't need to know
...

if conf.dev:
    conf.__dict__ = {**conf.__dict__, **local_conf}  # merges configurations
...

现在,只有您作为开发人员需要了解有关硬编码配置的任何信息。


对于开箱即用的方法,您可以使用argparse 功能从文件中读取配置。每行取一个值:

# Contents of configurations.txt
--debug
--loglevel
2

您使用魔术词实例化您的解析器,以便能够读取此配置文件:

parser = argparse.ArgumentParser(fromfile_prefix_chars='@')

然后您可以提供此配置前缀为@:

python main.py @configurations.txt

这与在命令行上提供configurations.txt 中的所有选项的效果相同。

【讨论】:

    【解决方案2】:

    您可以在local_conf 值中指定条件+默认值,例如:

    import argparse
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser()
        parser.add_argument("--debug", action="store_true")
        parser.add_argument("--loglevel")
        conf = parser.parse_args()
        default_level = 2
        local_conf = {
            "debug": conf.debug, # This will be False on absence of --debug 
            "loglevel": conf.loglevel if conf.loglevel else default_level
        }
    
        print(local_conf)
    

    这例如将使用2 作为默认级别,除非指定--loglevel。使用标志(argparse 的action="store_true")时,您需要决定是否要默认为TrueFalse

    所以在没有参数的情况下运行这个,local_conf 将打印:

    {'debug': False, 'loglevel': 2}

    使用--loglevel 5 --debug

    {'debug': True, 'loglevel': '5'}

    【讨论】:

    • 是的,试过了,但它放弃了在 argparse 初始化中设置默认值的可能性,我觉得最后更糟。感谢您的想法
    猜你喜欢
    • 2013-08-06
    • 2010-12-25
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    相关资源
    最近更新 更多