2013-09-18 3 views
0

Рассмотрим следующий сценарий:Есть ли способ очистить python argparse?

import argparse 
parser1 = argparse.ArgumentParser() 
parser1.add_argument('-a') 
args1 = parser1.parse_args() 

parser2 = argparse.ArgumentParser() 
parser2.add_argument('-b') 
args2 = parser2.parse_args() 

У меня есть несколько вопросов:

  1. Является parse_args метод единовременного или есть способ очистить аргументы, прежде чем добавлять новые? (например, что-то вроде args1.clear() или parser1.clear())
  2. Результат этого сценария неприменим. Хотя этот сценарий принимает аргумент -a, он не принимает никакого значения для 'a'. Также принимает любые аргументы -b. Есть ли способ заставить любой из аргументов действительно работать?
  3. Это мой реальный сценарий: у меня есть 2 скрипта. Оба импортируют тот же файл , который имеет код инициализации (загружает файлы конфигурации, создает регистраторы и т. Д.), Позволяет называть его init.py. Этот файл init.py также анализирует аргументы только потому, что ему требуется одно значение. Проблема заключается в том, что мне нужен один из скриптов для принятия других аргументов. Поскольку init.py что-то делает с одним аргументом, я не могу ждать с parse_args. Как я могу заставить его работать?

Edit:

Вот результат моего сценария:

[подсказка] # python2.7 myscript.py -a

использование: a.py [-h ] [-a А]

myscript.py: ошибка: аргумент -a: ожидается, один аргумент

[р rompt] # python2.7 myscript.py -a 1

пространство имен (а = '1')

использование: a.py [-h] [-b B]

myscript.py: ошибка: непризнанные аргументы: -a 1

ответ

2

Ваш сценарий вполне ясна, но я предполагаю, что вы ищете, parse_known_args

Здесь я понял, что вы назвали init.py из других файлов, скажем caller1.py и caller2.py

Также предположим, что init.py анализирует только аргумент -a, в то время как исходный скрипт будет анализировать остальные.

Вы можете сделать что-то вроде этого:

в init.py поместить это в do_things метод:

parser = argparse.ArgumentParser() 
parser.add_argument('-a') 
parsed = parser.parse_known_args(sys.argv) 
print 'From init.py: %s' % parsed['a'] 

В caller1.py:

init.do_things(sys.argv) 
parser = argparse.ArgumentParser() 
parser.add_argument('-b') 
parsed = parser.parse_known_args(sys.argv) 
print 'From caller1.py: %s' % parsed['b'] 

Если вы звоните caller1.py следующим образом: python caller1.py -a foo -b bar, то результатом будет:

From init.py: foo 
From caller1.py: bar 

Но если ваш сценарий на самом деле не так, Я бы предложил использовать @ Michael0x2a ответ, который просто использовать единый ArgumentParser объект в caller1.py и передать значение соответственно для init.py

+0

это здорово! только то, что мне нужно. Благодаря! – Ofir

2
  1. Это на самом деле не имеет смысла, так как во всех намерений и целей объект анализатор является лицом без гражданства. Нет ничего, что можно было бы очистить, поскольку все, что он делает, принимает аргументы консоли и возвращает объект Namespace (псевдодиск), не изменяя ничего в этом процессе.

    Таким образом, вы можете считать parse_args() идемпотентным. Вы можете неоднократно вызывать его снова и снова, и будет происходить тот же вывод. По умолчанию он будет читать аргументы от sys.argv, где хранятся аргументы консоли.

    Однако обратите внимание, что вы можете подключаться к пользовательским аргументам, передавая в список функцию parse_args, чтобы синтаксический анализатор использовал в качестве входного сигнала что-то другое, а затем sys.argv.

  2. Я не уверен, что вы имеете в виду. Если вы звоните python myscript.py -a 15, то args1 будет равно Namespace(a='15').Затем вы можете сделать args1['a'], чтобы получить значение 15. Если вы хотите, чтобы флаг действовал как переключатель, вызовите parser.add_argument('-a', action='store_true'). Вот a list всех доступных действий.

  3. Я бы попытался ограничить весь код консоли/интерфейса одним модулем и одним синтаксическим анализатором. В принципе, удалите код для синтаксического анализа командной строки из init.py, а второй - в независимый небольшой раздел. После запуска анализатора, который представляет единый интерфейс для всего в вашей программе, передайте соответствующие переменные функциям внутри init.py. Это имеет дополнительное преимущество в том, что пользовательский интерфейс является отдельным и более легко взаимозаменяемым с остальной частью кода.

Смежные вопросы