使用argparse在硬编码配置和命令行之间切换

时间:2017-12-27 13:08:04

标签: python configuration argparse

为了便于开发,我在代码中使用了硬编码的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 here

python main.py --from_bash --loglevel 3

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

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

2 个答案:

答案 0 :(得分: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中的所有选项具有相同的效果。

答案 1 :(得分:0)

您可以在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

所以在没有args的情况下执行此操作,local_conf将打印:

  

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

使用--loglevel 5 --debug

  

{'debug':是的,'loglevel':'5'}