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 (среди других причин).