Відповіді:
Зрештою, різниця між try, exceptі тестуванням len(sys.argv)не все така істотна. Вони обидва трохи хакітні порівняно з 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:]:. Це працює з позиційними аргументами, а підрахунок - ні.
Це звичайний список 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))