2013-09-17 3 views
3

Возможно, это глупый вопрос, но я не могу понять это.Какова область действия python argparse

Рассмотрим простой сценарий:

# file a.py 
from b import foo 
import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument('-a') 
args = parser.parse_args() 

# file b.py 
import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument('-b') 
args = parser.parse_args() 

foo = 1 

[подсказка] # питон a.py --help

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

необязательные аргументы: -h, --help показать эту справку и выйти -b B

То, что я не понимаю, - это то, как get.py принимает аргумент 'b' вместо 'a' . В другом примечании, как мне импортировать только переменную, а не весь файл? не должен «с b import foo» справиться с этим?

Edit: Я отправил еще один вопрос, касающийся того же вопроса, так как я до сих пор не знаю, как решить мою проблему (is there a way to clear python argparse?)

+0

Все, что вы не хотите запускать при импорте b, нужно зайти в блок 'if __name__'. Хотя вы можете определить парсер в b, вы, вероятно, не хотите запускать parse_args. В этом случае b parse_args столкнулся с '-h' и выпустил' sys.exit'. Входы, которые не вызвали ошибку, будут проанализированы обоими синтаксическими анализаторами. Но если вы хотите использовать аргументы, определенные парсером b, подумайте об импорте и передайте его как родительский парсер. – hpaulj

ответ

3

from b import foo примерно эквивалентно следующему:

import b 
foo = b.foo 
del b 

Хотя он «импортирует только foo», он все еще выполняет все заявления на верхнем уровне b.py (что необходимо для foo, чтобы быть полезным в любом случае), включая звонок по номеру parse.parse_args(). Этот вызов распечатает текст справки и полностью игнорирует вызовы argparse в a.py просто потому, что они еще не произошли.

Если вы хотите, чтобы ваши модули могли добавлять аргументы, вам необходимо отделить создание ArgumentParser от звонка до parse_args. Например, вы могли бы иметь отдельный args модуль:

# file args.py 
import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument('--common') 
... 

Он будет использоваться как из a.py и b.py:

# file a.py 
from b import foo 
import args 
args.parser.add_argument('-a') 

# only actually parse args if we are invoked as main script; mere `import a` 
# shouldn't run the parser 
if __name__ == '__main__': 
    args = parser.parse_args() 
    ... 

# file b.py 
import args 
args.parser.add_argument('-b') 

foo = 1 
+0

спасибо за быстрый и проницательный ответ. Предположим, что я должен делать вещи в b.py с аргументами, а b.py - не главный файл, есть ли способ обойти его? – Ofir

+0

@Ofir В этом случае я бы определил функцию в 'b.py', которая принимает аргументы и обрабатывает их, и вызывается эта функция из основного файла. – user4815162342

+0

Я все еще не уверен, как решить эту проблему как мой b.Файл py опирается на некоторые из этих аргументов, но вы ответили на мой первоначальный вопрос. 10x – Ofir

1

Вы должны только анализировать аргументы командной строки, если вы находитесь в __main__ пространстве имен. Чтобы предотвратить b.py от разбора аргументов, изменить его на следующее:

# file b.py 

foo = 1 

if __name__ == '__main__': 
    import argparse 
    parser = argparse.ArgumentParser() 
    parser.add_argument('-b') 
    args = parser.parse_args() 

Вы должны сделать так же для a.py.

+0

Это не сработает, если оба 'a' и' b' должны самостоятельно добавлять аргументы в парсер аргументов. Обратите внимание, что в коде OP 'a.py' добавляются' -a' и 'b.py' добавляет' -b', и OP хотел бы, чтобы полученный скрипт принял оба. – user4815162342

+0

Это не было частью вашего вопроса, но вы все еще можете это сделать. В этом случае вы должны создавать объект 'ArgumentParser', когда находитесь в' __main__', но все равно добавляете args в глобальную область каждого файла. – bogatron

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