Как лучше всего проверить, была ли передана переменная для сценария:
try:
sys.argv[1]
except NameError:
startingpoint = 'blah'
else:
startingpoint = sys.argv[1]
Ответы:
В конце концов, разница между try, exceptтестированием len(sys.argv)и не так уж и значительна. Они оба немного хакерские по сравнению с argparse.
Однако это приходит мне в голову - как своего рода малобюджетный argparse:
arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))
Вы даже можете использовать его для генерации 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для возврата значения по умолчанию, когда данное имя аргумента не имеет связанного значения в словаре.
Проверьте длину 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пункта.
argparse.
argparse.pyвсе мои проекты командной строки.
tryпредложение ... Итак, учитывая, что это не сложнее (и, IMO, немного красивее), я предпочитаю просто проверять длину (кроме того, вы избегаете того, чтобы люди кричать на вас за использование исключений для управления потоком).
tryДолжен признать, я немного извиняюсь. Я просто чувствую, что иногда это выражает мои намерения более ясно, чем ifзаявление.
Еще один способ, который я еще не видел в списке, - это заранее установить контрольное значение. Этот метод использует преимущества отложенного вычисления Python, при котором вам не всегда нужно предоставлять elseоператор. Пример:
startingpoint = 'blah'
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
Или, если вы используете синтаксис CRAZY, вы можете использовать тернарный оператор Python :
startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'
Я использую это - никогда не подводит:
startingpoint = 'blah'
if sys.argv[1:]:
startingpoint = sys.argv[1]
startingpointпеременную из примера, но вопрос заключается в назначении резервной переменной, поэтому я сделал то же самое.
sys.argv[1:]:. Это работает с позиционными аргументами, а count - нет.
Это обычный список Python. Исключением, которое вы могли бы поймать для этого, является IndexError, но вместо этого вам лучше просто проверить длину.
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
else:
startingpoint = 'blah'
Решение, работающее со встроенной функцией карты!
arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}
Тогда вам просто нужно вызвать свои параметры следующим образом:
if args['operation'] == "division":
if not args['parameter']:
...
if args['parameter'] == "euclidian":
...
Вы можете просто добавить значение argv [1] к argv, а затем проверить, не совпадает ли argv [1] с введенной вами строкой. Пример:
from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
print(argv[1])
Довольно близко к тому, что пытался сделать создатель. Вот функция, которую я использую:
def get_arg(index):
try:
sys.argv[index]
except IndexError:
return ''
else:
return sys.argv[index]
Таким образом, использование будет примерно таким:
if __name__ == "__main__":
banner(get_arg(1),get_arg(2))