Python: переключение с optparse на argparse
после переключения с optparse на argparse-я испытываю странные ошибки. Argparse анализирует args только если не оставляет места:
myScript.py -oOpt
или поставить знак равенства:
myScript.py -o=Opt
и это не работает нормально:
myScript.py -o Opt
вот моя инициализация argparse:
#!/usr/bin/env python
# to get description use the -h flag
import argparse, os, sys
# ======================
# Python2.7 is expected:
if sys.version_info[0] != 2 or sys.version_info[1] < 7:
sys.exit('This program needs Python2.7+')
# ==========
# preambule:
desc = """Enter dirs in the current dir and makes gro out of state.cpt there."""
# parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(description=desc, version='2.3', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-w', '--workWith',
help = 'to specify a Gromacs exec suffix',
dest = 'wW',
action = 'store',
default = '-4.5.5-single',
)
parser.add_argument('-g', '--gro',
help = '.gro postfix: <nameOfTheDir><postfix>.gro',
dest = 'myGroPostfix',
action = 'store',
default = "_membrane",
)
parser.add_argument('-H', '--here',
help = 'toggles - single (current) dir behaviour (the output will be state.gro)',
dest = 'Here',
action = 'store_true',
)
parser.add_argument('-D', '--dirs',
help = 'include these dirs (python's rgxp in SINGLE quotes), defaults to ''',
dest = 'inclDirs',
action = 'store',
default = '',
)
args = parser.parse_args()
print args.wW
редактировать:
еще:
gmx_bk-simulate-mems.py -j bk-runs-mpi.bash -p 1 -w="-4.5.5-double_non-parallel_gcc" 2&> ../`date +%Y-%b-%d-%H%M%S`.log &
выдает:
gmx_bk-simulate-mems.py: error: unrecognized arguments: 2
похоже argparse
лечит 2&>
как вариант (или 2&>
и ../date +%Y-%b-%d-%H%M%S.log
в качестве опции)!
Изменить 2:
Итак:
на
argparse
-"-4.5.5-double_non-parallel_gcc"
является плохим именем опции - и именно поэтому требуется написать как-w="-4.5.5-double_non-parallel_gcc"
. Дляoptparse
иbash
(! это нормально.bash
даже дает ошибку при-w="-4.5.5-double_non-parallel_gcc"
- он думает, что arg="-4.5.5-double_non-parallel_gcc"
(!);нет такой вещи, как
2&>
.2>
следует использовать, и это не дает никаких ошибок;это
shell
кто разбивает линию на args, а неpython
;argparse
намного лучше, чемoptparse
.
1 ответов
во-первых, необходимо сделать небольшое различие. The argparse
модуль не анализирует аргументы командной строки, это делает оболочка. Оболочка отвечает за преобразование строки, которую вы вводите в оболочке, в токены, которые затем передаются в sys.argv
, массив python / последовательность аргументов командной строки. The argparse
модуль просто имеет смысл того, что появляется в sys.argv
.
это различие прояснит обе" ошибки", которые вы заметили. Во-первых, рассмотрим -w "-4.5.5-double_non-parallel_gcc"
(Примечание отсутствие знака равенства). Оболочка анализирует эти два токена как -w
и -4.5.5-double_non-parallel_gcc
, и обе эти строки передаются в sys.аргв. Без знака равенства это, по-видимому, два варианта:-w
(без аргументов) и -4
С .5.5-double_non-parallel_gcc
в качестве аргумента. Вам нужен знак равенства, чтобы все анализировалось как один токен.
ОТРЕДАКТИРОВАННЫЙ РАЗДЕЛ
как 2&>
, argparse не может контролировать, является ли данный токен рассматривается как аргумент или нет. Если что-то появляется в sys.аргв, это значит твой shell рассматривает это как аргумент.
сигнальный знак здесь-это сообщение об ошибке. Обратите внимание, что сообщение не unrecognized arguments: 2&>
, а unrecognized arguments: 2
. Ваша оболочка распознает "& > " как перенаправление вывода и соответственно анализирует остальную часть строки (включая файл журнала). Единственный передаваемый аргумент - "2", потому что 2&>
не является реальным типом перенаправления. (&>
уже охватывает как stderr и stdout, так что бы 2
добавить к этому?)
в своем комментарии Вы утверждали, что optparse
можно "ручку" на "2&>". На самом деле это не так. The optparse
модуль сделал именно то, что argparse
, но optparse
не проверять аргументы типа argparse
делает. На самом деле,optparse
допускает реальную ошибку программирования (в этом случае, используя 2&>
как тип перенаправления оболочки) проскользнуть незамеченным! Вы должны размещать свой код optparse , но я подозреваю, что вы проанализировали свои аргументы следующим образом:--32-->
opt, args = parser.parse_args()
ваш сценарий не принимает позиционных аргументов, поэтому я предполагаю, что вы ничего не делали с args
далее. Но если бы вы проверили ... --25-->, вы обнаружите, что 2
считался позиционным аргументом!
в общем случае, если скрипт не принимает позиционных аргументов и вы используете optparse
, это хорошая практика, чтобы убедиться, что вы получите не аргументы, как Итак:
opt, args = parser.parse_args()
if args:
parser.error("script takes no positional arguments")
на argparse
модуль делает эту работу для вас, что ставит его на мили впереди optparse
(среди других причин).