如何处理不能一起使用的选项(使用 OptionParser)?
我的 Python 脚本(用于待办事项列表)是从命令行启动的,如下所示:
todo [options] <command> [command-options]
有些选项不能一起使用,例如
todo add --pos=3 --end "Ask Stackoverflow"
指定列表的第三个位置和末尾。同样,
todo list --brief --informative
我的程序也会因简短或信息丰富而感到困惑。由于我想要一个相当强大的选项控制,所以这样的情况会很多,而且以后肯定还会出现新的情况。如果用户传递了错误的选项组合,我想提供一条信息性消息,最好连同 optparse 提供的使用帮助一起。目前我用 if-else 语句来处理这个问题,我发现它真的很难看而且很糟糕。我的梦想是在我的代码中拥有这样的东西:
parser.set_not_allowed(combination=["--pos", "--end"],
message="--pos and --end can not be used together")
并且 OptionParser 在解析选项时会使用它。
据我所知,这并不存在,我向 SO 社区询问: 你如何处理这个问题?
My Python script (for todo lists) is started from the command line like this:
todo [options] <command> [command-options]
Some options can not be used together, for example
todo add --pos=3 --end "Ask Stackoverflow"
would specify both the third position and the end of the list. Likewise
todo list --brief --informative
would confuse my program about being brief or informative. Since I want to have quite a powerful option control, cases like these will be a bunch, and new ones will surely arise in the future. If a users passes a bad combination of options, I want to give an informative message, preferably along with the usage help provided by optparse. Currently I handle this with an if-else statement that I find really ugly and poor. My dream is to have something like this in my code:
parser.set_not_allowed(combination=["--pos", "--end"],
message="--pos and --end can not be used together")
and the OptionParser would use this when parsing the options.
Since this doesn't exist as far as I know, I ask the SO community:
How do you handle this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
可能通过扩展 optparse.OptionParser :
然后您可以在调用 parse_args 的地方处理 ConflictError :
Possibly by extending
optparse.OptionParser
:You can then handle
ConflictError
where you callparse_args
:Tamás 的答案是一个好的开始,但我无法让它工作,因为它有(或有)许多错误,包括
对 super 的调用失败,“解析器”<
Conflict.__slots__
中缺少 /code>,由于在Conflicts.accepts() 中使用了
等。parser.has_option()
,因此在指定冲突时始终会引发错误)由于我确实需要此功能,因此我推出了自己的解决方案,并从 Python 中获取它包索引为ConflictsOptionParser。它几乎可以替代
optparse.OptionParser
。 (我确实知道argparse
是新的命令行解析热点,但它在 Python 2.6 及更低版本中不可用,并且目前的采用率低于optparse
,如果您想破解或已经破解了额外的argparse
,请给我发送电子邮件。基于 code> 的解决方案。)关键是两个新方法,register_conflict()
,以及较小程度上的unregister_conflict()
:与由 Támas 开始的解决方案:
easy_install
,如果必须的话)。optparse.OptionParser.parse_args()
行为,并在检测到命令行参数中存在冲突选项时自动调用optparse.OptionParser.error()
,而不是抛出直接报错。 (这既是一个功能,也是一个错误;在optparse
的总体设计中是一个错误,但是这个包的一个功能,因为它至少与optparse
一致行为。)Tamás's answer is a good start, but I couldn't get it to work, as it has (or had) a number of bugs, including
a broken call to super,"parser"
missing inConflict.__slots__
, always raising an error when a conflict is specified because of the use ofparser.has_option()
inConflicts.accepts()
, etc.Since I really needed this feature, I rolled my own solution and have made it available from the Python Package Index as ConflictsOptionParser. It works pretty much as a drop in replacement for
optparse.OptionParser
. (I do knowargparse
is the new command line parsing hotness, but it is not available in Python 2.6 and below and has less adoption currently thanoptparse
. Send me an email if you'd like to hack up or have hacked up an additionalargparse
-based solution.) The key is two new methods,register_conflict()
, and, to a lesser extent,unregister_conflict()
:It has a few advantages over the solution begun by Támas:
easy_install
, if you must).optparse.Option
instances, which helps with the DRY principle; if you use the instances, you can change the actual strings without worrying about breaking conflict code.optparse.OptionParser.parse_args()
behavior and automatically callsoptparse.OptionParser.error()
when it detects conflicting options in the command line arguments, rather than throwing the error directly. (This is both a feature and a bug; kind of a bug inoptparse
's general design, but a feature for this package in that it is at least consistent withoptparse
behavior.)