Python argparse parse_args到全局命名空间(或者这是一个坏主意的原因)

时间:2013-10-10 15:11:38

标签: python argparse

我主要使用argparse在python中创建命令行脚本,我通常使用的习惯用法是将参数指定为对象的属性,然后将它们分别解析为与其属性名称匹配的变量。这似乎有点重复。有没有办法将它们全部分配到全局命名空间并删除分配步骤;或者通常情况下,当某些python行为对我来说似乎是违反直觉的时候,有些明智的,python专家指出,有一个很好的理由我不应该这样做或想要这样做吗?

我现在拥有的是:

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--db",type=str, dest='db', nargs='?', default="test")
    parser.add_argument("--collection",type=str, dest='collection', nargs='?', help="Collection, default is test", default="test")
    args = parser.parse_args()
    db = args.db                   # gross! 
    collection = args.collection   # yuck!
    print(db)
    print(collection)

我想要的是:

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--db",type=str, dest='db', nargs='?', default="test")
    parser.add_argument("--collection",type=str, dest='collection', nargs='?', help="Collection, default is test", default="test")
    parser.SUPER_parse_args() # now, db and collection are already in the namespace!
    print(db)
    print(collection)

当我只有2个参数时,它看起来并不多,但是如果我有10个左右,那么将赋值步骤加倍,在那里我将已经存在于args对象中的属性重命名为全局命名空间,开始弄错我。

3 个答案:

答案 0 :(得分:7)

可以使用globals执行此操作:

globals().update(args.__dict__)

然而,你真的* 不应该那样做。从蟒蛇的禅宗,

  

命名空间是一个很好的主意 - 让我们做更多的事情!

我会回应@Martijn在评论中所说的话:

  

别。只是不要。我会直接使用args

尽可能保持良好的分离。它使代码更易于维护和易于理解。

答案 1 :(得分:0)

这就是我所做的。它有助于可变碰撞,但不能保持可维护性。

parser_args = parser.parse_args()
if parser_args.verbose:
    globals().update(argparse.Namespace(verbose=parser_args.verbose).__dict__)

答案 2 :(得分:-1)

加入mgilson的答案:

请考虑使用locals().update(args.__dict__);这将更新当前命名空间而不是全局命名空间。

您也可以使用locals()或vars()来完成此操作。有关两者之间差异的详细解释,请参阅this Stack Overflow post

我对Mittonchops来说有点晚了,但希望这有助于其他人。