Есть ли способ, чтобы статические анализаторы 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.
Любые идеи?
Update
Вдохновленный ответом Остина ниже, самым простым решением, которое я смог найти, является использование 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
.