7

从 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

所以总结一下:

  • For argparse-"-4.5.5-double_non-parallel_gcc"是一个错误的选项名称 - 这就是为什么它需要写为 as -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;

  • argparseoptparse

4

1 回答 1

12

首先,有必要做一个小的区分。该argparse模块不会解析您的命令行参数,而 shell 会。shell 负责将您在 shell 中键入的行转换为标记,然后将其传递给sys.argvpython 数组/命令行参数序列。该argparse模块简单地理解出现在sys.argv.

这种区别将澄清您注意到的两个“错误”。首先,考虑-w "-4.5.5-double_non-parallel_gcc"(注意缺少等号)。shell 将这两个标记解析为-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()

你的脚本没有位置参数,所以我想你之后什么也没做args。但是,如果您要检查args,您会发现这2被认为是位置参数!

一般来说,如果脚本不接受位置参数并且您使用optparse,最好验证您是否收到位置参数,如下所示:

opt, args = parser.parse_args()
if args:
    parser.error("script takes no positional arguments")

argparse模块为您完成了这项工作,这使它领先了几英里optparse(除其他原因外)。

于 2012-04-11T14:36:05.573 回答