【问题标题】:python - Optional argument goofing with eval()python - 使用 eval() 处理可选参数
【发布时间】:2019-01-06 20:30:50
【问题描述】:

我正在尝试使用 argparse 进行解析。我有一个可选参数,称为 TileScheme:

parser.add_argument("--TileScheme", "--TS", default = PuertoRico2018)

我想将此参数的输入用作对象,所以我这样做:

TileScheme = eval(args.TileScheme)

但是,由于它是一个带有默认值的可选参数,我经常不想在可选参数中写入。我只想传递数值。但是,当我这样做时会收到此错误消息:

TypeError: eval() arg 1 must be a string or code object

即使 eval() 正在修改可选参数,它也会这么说!怎么办???

干杯! O.Fried

【问题讨论】:

  • args.TileScheme 将是 PuertoRico2018 对象(无论是什么),或者您的用户提供的字符串。我建议做一个print(args),这样你就可以清楚地知道解析器在做什么。您的处理代码需要考虑到这一点。
  • 如果TileScheme 应该是一个数字,那么int(args.TileScheme)(或float())比eval 更好。您也可以在解析器中使用type=int。如果default 不是字符串,则不会对其应用type
  • 它应该是一个字符串。当我执行 print(args) 时,我得到 'namespace(TileScheme=<__main__.tilescheme instance at>, X_coordinate=-60.1, Y_coordinate=18.4)'...
  • 我真正遇到的问题是程序将 TileScheme 视为位置参数,而它应该是可选的..
  • 非常感谢!

标签: eval argparse optional-arguments


【解决方案1】:
parser = ArgumentParser()
parser.add_argument("--TileScheme", "--TS")
args = parser.parse_args()

TileScheme = eval(args.TileScheme) if args.TileScheme is not None else PuertoRico

或者如果你很清楚:

if args.TileScheme is None:
    TileScheme = PuertoRico
else:
    TileScheme = eval(TileScheme)

In [116]: import argparse

定义一个类实例:

In [118]: class Foo():
     ...:     pass
     ...: 
In [119]: PR = Foo()
In [120]: PR
Out[120]: <__main__.Foo at 0x7f4cd94cd518>

解析器:

In [121]: parser = argparse.ArgumentParser()
In [122]: parser.add_argument('-f',default=PR);

没有参数:

In [123]: args = parser.parse_args([])
In [124]: print(args)
Namespace(f=<__main__.Foo object at 0x7f4cd94cd518>)

字符串的 eval 有效,但普通的 args.f 也有效:

In [125]: eval('args.f')
Out[125]: <__main__.Foo at 0x7f4cd94cd518>
In [126]: args.f
Out[126]: <__main__.Foo at 0x7f4cd94cd518>

现在使用用户定义的字符串:

In [128]: args = parser.parse_args(['-f','PR'])
In [129]: args
Out[129]: Namespace(f='PR')
In [130]: eval('args.f')     # eval of the string doesn't help
Out[130]: 'PR'
In [131]: eval(args.f)       # eval of the value does
Out[131]: <__main__.Foo at 0x7f4cd94cd518>

我早先建议您可以进行isinstance 测试,而不是None 测试:

In [132]: if isinstance(args.f, Foo):
     ...:     print(args.f)
     ...: else:
     ...:     print(eval(args.f))
     ...:     
<__main__.Foo object at 0x7f4cd94cd518>
In [133]: args = parser.parse_args([])
In [134]: if isinstance(args.f, Foo):
     ...:     print(args.f)
     ...: else:
     ...:     print(eval(args.f))
     ...:     
<__main__.Foo object at 0x7f4cd94cd518>

或者测试args.f是否是一个字符串。

【讨论】:

    【解决方案2】:

    哎呀:我不得不用引号写TileScheme = eval("args.TileScheme") :) 感谢@hpaulj 的帮助!!

    【讨论】:

    • 我看不出引用字符串的eval 有什么帮助。查看我的编辑。
    猜你喜欢
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    相关资源
    最近更新 更多