有没有办法让Python静态分析器(例如PyCharm、其他IDE)捕获argparse.Namespace对象上的 Typehints? 例如:
argparse.Namespace
parser = argparse.ArgumentParser()
parser.add_argument('--somearg')
parsed = parser.parse_args(['--somearg','someval']) # type: argparse.Namespace
the_arg = parsed.somearg # <- Pycharm complains that parsed object has no attribute 'somearg'
如果我在内联注释中移除类型声明,PyCharm 不会报错,但也不会检测无效的属性。例如:
parser = argparse.ArgumentParser()
parser.add_argument('--somearg')
parsed = parser.parse_args(['--somearg','someval']) # no typehint
the_arg = parsed.somaerg # <- typo in attribute, but no complaint in PyCharm. Raises AttributeError when executed.
有什么想法吗?
更新
受Austin的回答启发,我找到的最简单的解决方案是使用namedtuples
:
from collections import namedtuple
ArgNamespace = namedtuple('ArgNamespace', ['some_arg', 'another_arg'])
parser = argparse.ArgumentParser()
parser.add_argument('--some-arg')
parser.add_argument('--another-arg')
parsed = parser.parse_args(['--some-arg', 'val1', '--another-arg', 'val2']) # type: ArgNamespace
x = parsed.some_arg # good...
y = parsed.another_arg # still good...
z = parsed.aint_no_arg # Flagged by PyCharm!
虽然这样是可以接受的,但我仍然不喜欢重复参数的名称。如果参数列表变得相当庞大,更新两个位置将很繁琐。理想情况下,应该从parser
对象中提取参数,如下所示:
parser = argparse.ArgumentParser()
parser.add_argument('--some-arg')
parser.add_argument('--another-arg')
MagicNamespace = parser.magically_extract_namespace()
parsed = parser.parse_args(['--some-arg', 'val1', '--another-arg', 'val2']) # type: MagicNamespace
我没有在
argparse
模块中找到任何可以实现这一点的东西,而且我仍然不确定是否有任何静态分析工具可以聪明地获取那些值而不会使IDE停滞不前。继续搜索...
更新2
根据hpaulj的评论,最接近描述上述方法的东西是从解析器的每个_action
中提取dest
属性的东西。parser = argparse.ArgumentParser()
parser.add_argument('--some-arg')
parser.add_argument('--another-arg')
MagicNamespace = namedtuple('MagicNamespace', [act.dest for act in parser._actions])
parsed = parser.parse_args(['--some-arg', 'val1', '--another-arg', 'val2']) # type: MagicNamespace
但是这仍然无法导致属性错误在静态分析中被标记。如果我在parser.parse_args
调用中传递namespace=MagicNamespace
,情况也是如此。
parser = argparse.ArgumentParser() # type: argparse.Namespace
上使用它,看看是否有效。 - aghastparser
是一个argparse.ArgumentParser
对象,而不是一个argparse.Namespace
对象。我希望parsed
对象被填充为参数属性。 - Billyparsed
和parser
的区别。你真正想要的似乎是PyCharm在构建ArgumentParser时解析方法参数。我怀疑这样做是否有效。 - aghastadd_argument
返回它刚创建的Action
对象。查看它的属性。parser._actions
是所有这些操作的列表,解析器在解析过程中使用它们。我在之前的 SO 回答中提到过它们。 - hpauljparse_args
函数? - hpaulj