python - 你如何处理不能一起使用的选项(使用 OptionParser)?

标签 python optparse

我的 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 社区: 你如何处理这个问题?

最佳答案

可能通过扩展 optparse.OptionParser:

class Conflict(object):
    __slots__ = ("combination", "message", "parser")

    def __init__(self, combination, message, parser):
        self.combination = combination
        self.message = str(message)
        self.parser = parser

    def accepts(self, options):
        count = sum(1 for option in self.combination if hasattr(options, option))
        return count <= 1

class ConflictError(Exception):
    def __init__(self, conflict):
        self.conflict = conflict

    def __str__(self):
        return self.conflict.message

class MyOptionParser(optparse.OptionParser):
    def __init__(self, *args, **kwds):
        optparse.OptionParser.__init__(self, *args, **kwds)
        self.conflicts = []

    def set_not_allowed(self, combination, message):
        self.conflicts.append(Conflict(combination, message, self))

    def parse_args(self, *args, **kwds):
        # Force-ignore the default values and parse the arguments first
        kwds2 = dict(kwds)
        kwds2["values"] = optparse.Values()
        options, _ = optparse.OptionParser.parse_args(self, *args, **kwds2)

        # Check for conflicts
        for conflict in self.conflicts:
            if not conflict.accepts(options):
                raise ConflictError(conflict)

        # Parse the arguments once again, now with defaults
        return optparse.OptionParser.parse_args(self, *args, **kwds)

然后您可以在调用 parse_args 的地方处理 ConflictError:

try:
    options, args = parser.parse_args()
except ConflictError as err:
    parser.error(err.message)

关于python - 你如何处理不能一起使用的选项(使用 OptionParser)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2729426/

相关文章:

python - pythons lambda 可以用来改变另一个函数的内部工作吗?

python - 需要 MacOS 11 或更高版本! PyCharm 上的错误

python - 阅读 ID3 标签的最佳库是什么?

python - 根据列值而不是索引值从 Pandas 数据框中排除行

python - 将 cv2 图像转换为 PySDL2 表面以传输到屏幕

ruby - Ruby 中的 OptionParse 和不以 '-' 开头的参数

python - 如何知道 optparse 选项是在命令行中传递的还是作为默认选项传递的

Python optparse 和参数中的空格

python - optparse 在 python 中使用消息字符串?

python - 使用 python optparse 和 lambda 作为回调的问题