我主要使用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对象中的属性重命名为全局命名空间,开始弄错我。
答案 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来说有点晚了,但希望这有助于其他人。