有没有办法让 Python 静态分析器(例如在 PyCharm 中,其他 IDE 中)在对象上的 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.
有任何想法吗?
更新
受奥斯汀下面回答的启发,我能找到的最简单的解决方案是使用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 的评论,我能找到的最接近上述方法的“神奇地”提取已解析对象的属性的方法是dest
从每个解析器的_action
s 中提取属性:
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
但这仍然不会导致属性错误在静态分析中被标记。如果我通过电话,这也是正确namespace=MagicNamespace
的parser.parse_args
。