2012-05-22 2 views
30

Мой скрипт должен начать демонстрационный режим, когда не указаны параметры. Я попытался это:Argparse: проверить, были ли переданы какие-либо аргументы.

args = parser.parse_args() 
if len(args) == 0: 
    run_demo() 
else: 
    # evaluate args 

который дает *** TypeError: object of type 'Namespace' has no len() в args нет списка.

Как достичь того, что я хочу?

+0

использование пытаются кроме захвата TypeError, так что вы знаете, что ничего не было передано – avasal

+7

@avasal, 'LEN (арг)' всегда бросает TypeError. – huon

ответ

50

Если ваша цель состоит в том, чтобы определить, когда не аргумент не было дано команды, то делает это с помощью argparse неправильный подход (как Бен хорошо указал).

Подумайте просто! :-) Я считаю, что argparse не опустошает sys.argv. Итак, if not len(sys.argv) > 1, тогда пользователю не было представлено никаких аргументов.

+0

это работает, и, вероятно, это лучший/самый простой способ сделать это: D –

+0

Принял этот ответ, поскольку он решает мою проблему, Мне нужно переосмыслить все. => bad me;) – Framester

+0

+1 Более практичный совет по данной проблеме, чем мое предложение проверить * все * варианты против 'Нет'. – Ben

14

argparse позволяет вам установить (внутри объекта пространства имен) все переменные, упомянутые в аргументах, добавленных в парсер, на основе вашей спецификации и анализируемой командной строки. Если вы установите значение по умолчанию, то эти переменные будут иметь это значение по умолчанию, если они не были видны в командной строке, они не будут отсутствовать в объекте пространства имен. И если вы не укажите значение по умолчанию, то есть неявное значение по умолчанию None. Таким образом, проверка длины объекта пространства имен, однако вам удается это сделать, не имеет смысла как способ проверить, были ли проанализированы любые аргументы; он всегда должен иметь одинаковую длину.

Вместо этого, если вы знаете, что у вас есть куча аргументов без настроек по умолчанию, и вы хотите проверить, было ли какое-либо из них установлено значение любого значения None ... сделайте это. Вы можете использовать понимание списка и функцию vars, чтобы перебрать их, не дублируя список имен из вызовов add_argument, как показано в ответе Martijn.

Это немного сложнее, если некоторые из ваших аргументов имеют значения по умолчанию, и, более того, если они имеют значения по умолчанию, которые могут быть явно указаны в командной строке (например, числовой аргумент, который по умолчанию равен 0, делает невозможным по умолчанию от пользователя, предоставляющего 0). В этом случае я не уверен, что существует общее решение, которое всегда работает без знания того, что такое аргументы.

+2

Это хорошо объясняет, почему у вас «неправильная проблема» :) –

+0

+1 для понимания – Framester

4

Если вам действительно нужен номер аргумента (по какой-либо причине). Я нашел этот код очень полезным (но не знаю, насколько он оптимизирован, и я был бы признателен за любые комментарии к нему).

args = parser.parse_args() 
print(len(vars(args))) 

В этой версии учитываются только параметры -xx, а не какое-либо дополнительное значение.

Если вы хотите все (также значения пройдены), то просто используйте len(sys.argv), как упоминалось ранее.

0

я расширил понятие 2dvisio, чтобы рассчитывать не ноль или None аргументов:

vm_opts = parser.parse_args() 
v = vars(vm_opts) 
n_args = sum([ 1 for a in v.values() if a]) 
1

Примет следующий пример, чтобы продлить Yours для полноты:

#!/usr/bin/env python3 

import argparse 

... 
def main(): 
    parser = argparse.ArgumentParser() 
    parser.add_argument('input', nargs='?' action='store') 
    parser.add_argument('-l', '--length', type=int, action='store') 
    parser.add_argument('-v', '--verbose', action='store_true') 
    args = parser.parse_args() 
    if (args.input == None and args.length == None): 
     parser.print_help() 
    else: 
     print(args) 

if __name__ == '__main__': 
    main() 

Вашего объекта пространства имен, упомянутой @Ben , в этом примере args. Из строк в parser.add_argument создается переменная.Вы можете получить к нему доступ через args.input или args.length или args.verbose. Вы можете проверить это, выполнив print(args), которая на самом деле показать что-то вроде этого:

Namespace(input=None, length=None, verbose=False) 

так многословен установлен в True, если он присутствует, и вход и длина только переменные, которые не должны быть созданы (без аргументов предоставлена).

Также полезно использовать group = parser.add_mutually_exclusive_group(), если вы хотите обеспечить, два атрибута не могут быть предоставлены одновременно.

Для получения дополнительной справки, пожалуйста, обращайтесь:

0

Не используйте argparse. Вместо этого просто используйте sys.argv. argparse создает пространство имен, поэтому он всегда будет давать вам «dict» с их значениями, в зависимости от того, какие аргументы вы использовали при вызове сценария.

Вот что я сделал в прошлом:

args = parser.parse_args() 
if len(sys.argv) == 1: 
    parser.print_help() 
    sys.exit() 
return args 

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

  • Нет связанных вопросов^_^