【问题标题】:How to store an 'args.foo' value to a 'bar' variable?如何将“args.foo”值存储到“bar”变量中?
【发布时间】:2022-01-20 18:34:30
【问题描述】:

我一直在为我的最新项目使用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.learning_rate。那是自动的。如果您不想要它,为什么要将它复制到另一个参考?
  • "我尽量避免使用带有 'args.' 的变量。前缀“为什么?
  • 您可以修改全局范围,但您真的不应该,“命名空间是一个很棒的想法——让我们做更多的事情!”。您不能在本地范围内执行此操作。但同样,这不是问题,因为您真的可能不应该
  • 我认为关键是,您想在 local 范围内分散args.learning_rate。在定义args 的范围内使用args.learning_rate,但如果您需要函数中的值,请不要将args 用作全局:将args.learning_rate 作为参数 传递给函数,它会在你调用时对函数的参数进行隐式赋值。

标签: python python-3.x argparse


【解决方案1】:

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

但是这样的东西可以用在代码打高尔夫球中,所以我将提供一种“神秘”的方式来做这件事,假设你有几个你不想逐行重新分配的参数。

您可以使用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 可能更合适如果您采用这种方法。

【讨论】:

    【解决方案2】:

    当你调用一个函数时,一个实参被隐式赋值给一个形参。

    在定义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在调用时会如何设置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-11
      • 1970-01-01
      • 2016-05-10
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多