Вы даже можете использовать его для генерации namedtupleсо значениями по умолчанию None- всего в четырех строках!
Arg_list= collections.namedtuple('Arg_list', arg_names)
args =Arg_list(*(args.get(arg,None)for arg in arg_names))
Если вы не знакомы с этим namedtuple, это просто кортеж, который действует как объект, позволяя вам получить доступ к его значениям, используя tup.attributeсинтаксис вместо tup[0]синтаксиса.
Итак, первая строка создает новый namedtupleтип со значениями для каждого из значений в arg_names. Вторая строка передает значения из argsсловаря, используя getдля возврата значения по умолчанию, когда данное имя аргумента не имеет связанного значения в словаре.
Я люблю Python все больше и больше, все благодаря таким ответам и, конечно же, Stack Overflow! Жаль, что у нас нет объяснения последних двух строк. Я считаю, что для новичков это было бы здорово.
Goujon
2
Любить это! Лучшее решение этой проблемы, которое я видел. Для других: для меня не сразу было очевидно (newb), что: 1) 'команда' будет каждый раз проходить как первый аргумент и 2) вы можете вызывать результаты с помощью args [0] и т. Д.
Мэтт Д.
Это конечно круто, но что за хакерство в тестировании длины?
colorlace
1
@timwiz Я говорил только по сравнению с использованием argparse. Тем не менее, в наши дни я бью себя каждый раз, когда возвращаюсь к старому скрипту и обнаруживаю, что не использовал argparse.
senderle 09
117
Проверьте длину sys.argv:
if len(sys.argv)>1:
blah = sys.argv[1]else:
blah ='blah'
Некоторые люди предпочитают подход, основанный на исключениях, который вы предложили (например, try: blah = sys.argv[1]; except IndexError: blah = 'blah'), но мне он не нравится, потому что он не так хорошо «масштабируется» (например, когда вы хотите принять два или три аргумента) и он потенциально может скрыть ошибки (например, если вы использовали blah = foo(sys.argv[1]), но foo(...)подняли IndexError, это IndexErrorбудет проигнорировано).
Но пока вы относитесь к этому атомарно, вам не о чем беспокоиться try, except. Просто дождитесь fooсвоего аргумента до elseпункта.
senderle
3
Кроме того, если вы задумались о масштабировании, пора переходить к argparse.
senderle
1
+1 на argparse. У меня есть argparse.pyвсе мои проекты командной строки.
Дэвид Волевер
2
@senderle: конечно, если вы прилежны, ничего страшного. Но по моему опыту, большинство программистов не усердны и не вкладывают всю логику в tryпредложение ... Итак, учитывая, что это не сложнее (и, IMO, немного красивее), я предпочитаю просто проверять длину (кроме того, вы избегаете того, чтобы люди кричать на вас за использование исключений для управления потоком).
Дэвид Волевер
2
@ Дэвид, да, я понимаю твою точку зрения. tryДолжен признать, я немного извиняюсь. Я просто чувствую, что иногда это выражает мои намерения более ясно, чем ifзаявление.
senderle
22
Еще один способ, который я еще не видел в списке, - это заранее установить контрольное значение. Этот метод использует преимущества отложенного вычисления Python, при котором вам не всегда нужно предоставлять elseоператор. Пример:
Ответ тернарного оператора на мой взгляд самый красивый. Я сижу здесь и тихо проклинаю тот факт, что часть поддерживаемого мной программного обеспечения привязано к Python 2.4, на котором его нет.
Это не для проверки, если определено. Это больше похоже на определение, если существует, что не то же самое. Я тоже использовал этот способ для задания резервных переменных, но это не ответ на текущий вопрос.
m3nda,
@ erm3nda Я могу удалить startingpointпеременную из примера, но вопрос заключается в назначении резервной переменной, поэтому я сделал то же самое.
анатолий техтоник
1
Если вы удалите его, вы получите ошибку о том, что переменная не определена. Я снова прочитал вопрос, и он ожидает, что это замена переменной :), так что все в порядке. Спасибо за совет о таком коротком пути if sys.argv[1:]:. Это работает с позиционными аргументами, а count - нет.
m3nda
10
Это обычный список Python. Исключением, которое вы могли бы поймать для этого, является IndexError, но вместо этого вам лучше просто проверить длину.
if len(sys.argv)>=2:
startingpoint = sys.argv[1]else:
startingpoint ='blah'
для тех, кто проголосовал против меня, позор вам, за то, что не разъяснили ошибку.
Хасан Абдул-Карим
Думаю, это потому, что это хакерское занятие. Что, если кто-то передаст SomeString в качестве аргумента? Как это использовать, если вы можете принять, скажем, от 1 до 5 аргументов?
пбогут
Круто (но все же хакерское) для установки значения по умолчанию в случае, если пользователь не предоставляет аргумент. Просто добавьте, а затем используйте argv [1].
Felizett
1
Довольно близко к тому, что пытался сделать создатель. Вот функция, которую я использую:
Ответы:
В конце концов, разница между
try, except
тестированиемlen(sys.argv)
и не так уж и значительна. Они оба немного хакерские по сравнению сargparse
.Однако это приходит мне в голову - как своего рода малобюджетный argparse:
Вы даже можете использовать его для генерации
namedtuple
со значениями по умолчаниюNone
- всего в четырех строках!Если вы не знакомы с этим
namedtuple
, это просто кортеж, который действует как объект, позволяя вам получить доступ к его значениям, используяtup.attribute
синтаксис вместоtup[0]
синтаксиса.Итак, первая строка создает новый
namedtuple
тип со значениями для каждого из значений вarg_names
. Вторая строка передает значения изargs
словаря, используяget
для возврата значения по умолчанию, когда данное имя аргумента не имеет связанного значения в словаре.источник
Проверьте длину
sys.argv
:Некоторые люди предпочитают подход, основанный на исключениях, который вы предложили (например,
try: blah = sys.argv[1]; except IndexError: blah = 'blah'
), но мне он не нравится, потому что он не так хорошо «масштабируется» (например, когда вы хотите принять два или три аргумента) и он потенциально может скрыть ошибки (например, если вы использовалиblah = foo(sys.argv[1])
, ноfoo(...)
поднялиIndexError
, этоIndexError
будет проигнорировано).источник
try, except
. Просто дождитесьfoo
своего аргумента доelse
пункта.argparse
.argparse.py
все мои проекты командной строки.try
предложение ... Итак, учитывая, что это не сложнее (и, IMO, немного красивее), я предпочитаю просто проверять длину (кроме того, вы избегаете того, чтобы люди кричать на вас за использование исключений для управления потоком).try
Должен признать, я немного извиняюсь. Я просто чувствую, что иногда это выражает мои намерения более ясно, чемif
заявление.Еще один способ, который я еще не видел в списке, - это заранее установить контрольное значение. Этот метод использует преимущества отложенного вычисления Python, при котором вам не всегда нужно предоставлять
else
оператор. Пример:Или, если вы используете синтаксис CRAZY, вы можете использовать тернарный оператор Python :
источник
Я использую это - никогда не подводит:
источник
startingpoint
переменную из примера, но вопрос заключается в назначении резервной переменной, поэтому я сделал то же самое.sys.argv[1:]:
. Это работает с позиционными аргументами, а count - нет.Это обычный список Python. Исключением, которое вы могли бы поймать для этого, является IndexError, но вместо этого вам лучше просто проверить длину.
источник
Решение, работающее со встроенной функцией карты!
Тогда вам просто нужно вызвать свои параметры следующим образом:
источник
Вы можете просто добавить значение argv [1] к argv, а затем проверить, не совпадает ли argv [1] с введенной вами строкой. Пример:
источник
Довольно близко к тому, что пытался сделать создатель. Вот функция, которую я использую:
Таким образом, использование будет примерно таким:
источник