如何将 'args.foo' 值存储到 'bar' 变量?

How to store an 'args.foo' value to a 'bar' variable?

我最近的项目一直在使用 argparse,虽然它非常有用,但我意识到大多数时候,尤其是在较长的脚本中,我尽量避免将变量与 'args.' 前缀,所以像这样的行使我的代码膨胀:

parser.add_argument('--learning_rate', '--lr', default=0.0005, type=float, help='defines the learning_rate variable for the model.')
learning_rate = args.learning_rate

是否有一个选项可以自动将传递给 --learning_rate 的内容存储到 learning_rate 中,从而避免第二行代码?

感谢您的时间和关注。

调用函数时,参数会隐式分配给参数。

在定义 args 的相同范围内,我会继续使用 args.learning_rate 来强调它是一个配置选项。但不是写

def foo(x):
    return x * args.learning_rate

y = foo(3)

def foo(x, learning_rate):
    return x * learning_rate

y = foo(args.learning_rate)

阅读foo的定义时,你不关心learning_rate在调用时如何设置。

正如其他人所说,删除引用 args.learning_rate 的行会导致其他人发现您的代码神秘或令人困惑。

但是类似这样的东西可以用在代码高尔夫中,所以我会提供一种 'cryptic' 的方法来做到这一点,前提是你有几个你不想逐行重新分配的参数-行.

您可以使用 vars() 内置函数或 __dict__ 属性获取 args 的字典。
请参考What is the right way to treat Python argparse.Namespace() as a dictionary.

>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> d = vars(args)
>>> d
{'foo': 1, 'bar': [1, 2, 3]}

之后您可以将这些键转换为变量并将值分配给变量,如下所示:

for k, v in d.items():
    exec(f'{k} = {v}')
print(foo) # 1
print(bar) # [1, 2, 3]

请参阅 Using a string variable as a variable name 以进一步了解为什么 exec() 可能是不好的做法而 setattr 可能更合适 if你用这个方法。