如何在 Python docopt 用法中使用程序的实际调用?

How to use the actual invocation of the program in Python docopt usages?

我正在尝试使用 Python 中的 docopt 模块来解析脚本的命令行参数。该脚本可以直接调用,也可以通过使用 PyInstaller 构建的 .exe 调用。我想在用法部分使用程序的实际名称,这根据程序的调用方式而有所不同(请注意,这里有更多相互排斥的选项,我已经删除了):

> py script.py
  Usage:
      script.py -foo <foo>
      script.py -bar <bar>
      ...

> dist/script.exe
  Usage:
      dist/script.exe -foo <foo>
      dist/script.exe -bar <bar>
      ...

我可以通过在传递给 docopt 的字符串上使用 .format() 来做到这一点,但这变得很难看并且阻止将选项指定为模块文档字符串:

doc = """
  Usage:
      {} -foo <foo>
      {} -bar <bar>
      ...
  """.format(sys.argv[0], sys.argv[0])
args = docopt(doc, ...)

有没有更好的方法?

正如您在当前 master 分支中的 inspecting the code 中看到的那样,docopt 并没有做太多的工作来获取它解析和显示的字符串。

但是 DocoptExit exception it raises 实际显示的是用法消息,因此您可以猴子修补,如下面 test.py 所示

""" Usage:
    PROGRAM --foo <foo>
    PROGRAM --bar <bar>
"""
import sys, docopt

class MyExit(SystemExit):
    usage = ''
    def __init__(self, message=''):
        usage = self.usage.replace("PROGRAM",sys.argv[0])
        SystemExit.__init__(self, (message + '\n' + usage).strip())

docopt.DocoptExit = MyExit
args = docopt.docopt(__doc__, version='0.0.1-alpha')
print str(args)

样本运行

bash-3.2$ python test.py
Usage:
    test.py --foo <foo>
    test.py --bar <bar>

bash-3.2$ python test.py --foo foo
{'--bar': False,
 '--foo': True,
 '<bar>': None,
 '<foo>': 'foo'}