Каким будет лучший способ проверить, была ли передана переменная для script:
try:
sys.argv[1]
except NameError:
startingpoint = 'blah'
else:
startingpoint = sys.argv[1]
Каким будет лучший способ проверить, была ли передана переменная для script:
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
будет проигнорирован).
Еще один способ, которого я еще не видел, - это заранее установить значение дозорного. Этот метод использует преимущества ленивой оценки 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'
Это обычный список Python. Исключением, которое вы поймаете для этого, является IndexError, но вам лучше просто проверить длину.
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
else:
startingpoint = 'blah'
Я использую это - он никогда не прерывается:
startingpoint = 'blah'
if sys.argv[1:]:
startingpoint = sys.argv[1]
Вы можете просто добавить значение 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))
Решение, работающее с встроенной картой карты!
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":
...