Python:从optparse切换到argparse

Ado*_*obe 6 python shell optparse command-line-arguments argparse

从optparse切换到argparse后 - 我遇到了奇怪的错误.Argparse仅在不留空间时解析args:

myScript.py -oOpt
Run Code Online (Sandbox Code Playgroud)

或者给出一个等号:

myScript.py -o=Opt
Run Code Online (Sandbox Code Playgroud)

并且它不能正常工作:

myScript.py -o Opt
Run Code Online (Sandbox Code Playgroud)

这是我的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
Run Code Online (Sandbox Code Playgroud)

编辑:

更:

 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 &
Run Code Online (Sandbox Code Playgroud)

得到:

 gmx_bk-simulate-mems.py: error: unrecognized arguments: 2
Run Code Online (Sandbox Code Playgroud)

它看起来像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".对于optparsebash(!)这很好.bash甚至给出错误-w="-4.5.5-double_non-parallel_gcc"- 它认为arg是="-4.5.5-double_non-parallel_gcc"(!);

  • 没有这样的事情2&>.2>应该使用,它没有错误;

  • 这是shell谁将线分成args,而不是python;

  • argparse好多了optparse.

Har*_*wEm 12

首先,有必要进行小的区分.该argparse模块不解析您的命令行参数,外壳一样.shell负责将您在shell中键入的行转换为标记,然后将标记传递给sys.argvpython数组/命令行参数序列.该argparse模块只是理解出现的内容sys.argv.

这种区别将澄清您注意到的两个"错误".首先,考虑-w "-4.5.5-double_non-parallel_gcc"(注意缺少等号).壳解析这两个标记为-w-4.5.5-double_non-parallel_gcc,而这两个字符串传递给sys.argv中.如果没有等号,这似乎是两个选项:-w(无参数)和-4.5.5-double_non-parallel_gcc作为参数.您需要等号,以便将所有内容解析为单个令牌.

编辑部分

至于2&>,argparse不可能控制给定的令牌是否被视为参数.如果sys.argv中出现某些内容,则表示您的shell将其视为参数.

这里的告示标志是错误消息.请注意,消息不是unrecognized arguments: 2&>,而是unrecognized arguments: 2.您的shell将"&>"识别为输出重定向,并相应地解析该行的其余部分(包括日志文件).传递的唯一参数是"2",因为2&>它不是真正的重定向类型.(&>已经涵盖了stderr和stdout,那么2添加它会是什么?)

在评论中,您声称optparse可以"处理""2&>".事实并非如此.该optparse模块完全做了什么argparse,但optparse不验证位置参数argparse.实际上,optparse让一个真正的编程错误(在这种情况下,使用2&>作为一种shell重定向)会被检测不到!您应该发布原始的optparse代码,但我怀疑您解析了您的参数,如下所示:

opt, args = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

你的脚本没有位置参数,所以我想你args事后没有做任何其他事情.但如果你要检查args,你会发现这2被认为是一种位置论证!

通常,如果脚本没有使用位置参数并且您使用optparse,则最好验证您没有收到位置参数,如下所示:

opt, args = parser.parse_args()
if args:
    parser.error("script takes no positional arguments")
Run Code Online (Sandbox Code Playgroud)

argparse模块可以帮助您实现这一目标,这使得它远远领先optparse于其他原因(除其他原因外).