在我的脚本中搜索更快的方法来解析命令行参数时,我遇到了argh library。
我非常喜欢argh的功能但是我遇到了一个阻止我使用它的缺点,这与我在调用-help选项时显示的默认帮助消息有关: 默认情况下,函数的docstring显示在参数列表的顶部。这很好,但初始格式丢失了。例如,请参阅以下示例脚本
import argh
def func(foo=1, bar=True):
"""Sample function.
Parameters:
foo: float
An example argument.
bar: bool
Another argument.
"""
print foo, bar
argh.dispatch_command(func, argv=['-h'])
会导致以下输出
usage: script.py [-h] [-f FOO] [-b]
Sample function. Parameters: foo: float An example argument. bar: bool Another
argument.
optional arguments:
-h, --help show this help message and exit
-f FOO, --foo FOO
-b, --bar
是否有(简单)方法获得如下输出?
usage: script.py [-h] [-f FOO] [-b]
Sample function.
Parameters:
foo: float
An example argument.
bar: bool
Another argument.
optional arguments:
-h, --help show this help message and exit
-f FOO, --foo FOO
-b, --bar
我宁愿不使用注释来定义参数帮助消息,因为这需要我在每次有变化时都改变函数的文档字符串和帮助文本。
答案 0 :(得分:6)
我不熟悉argh
,但显然它是argparse
的包装器。我的猜测是它正在使用你的函数__doc__
,并使它成为解析器的description
,例如。
parser = argparse.ArgumentParser(description=func.__doc__)
https://docs.python.org/2.7/library/argparse.html#argparse.RawDescriptionHelpFormatter
argparse
有RawDescriptionHelpFormatter
,按原样显示说明。
parser = argparse.ArgumentParser(description=func.__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
所以问题是,有没有办法让argh
使用这个格式化程序?
这个argparse
脚本会产生您想要的帮助:
import argparse
def func(foo=1, bar=True):
"""Sample function.
Parameters:
foo: float
An example argument.
bar: bool
Another argument.
"""
print foo, bar
parser = argparse.ArgumentParser(prog='script.py',
description=func.__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-f', '--foo', type=float)
parser.add_argument('-b', '--bar', action='store_false')
parser.print_help()
在argh/dispatching.py
def dispatch_command(function, *args, **kwargs):
...
parser = argparse.ArgumentParser(formatter_class=PARSER_FORMATTER)
set_default_command(parser, function)
dispatch(parser, *args, **kwargs)
所以你可以设置:
PARSER_FORMATTER = argparse.RawDescriptionHelpFormatter
或编写自己的函数:
def raw_dispatch_command(function, *args, **kwargs):
...
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
set_default_command(parser, function)
dispatch(parser, *args, **kwargs)
答案 1 :(得分:3)
在@hpaulj的帮助下,我终于设法获得了理想的行为。为了方便这一点,我定义了一个类似于argh.arg的自定义装饰器,目标是不必单独为每个参数写@argh.arg(‘—param’, help=“%(default)s”)
,而是在我的函数上只使用一个@arg_custom()
装饰器:
def arg_custom():
from argh.constants import ATTR_ARGS
from argh.assembling import _get_args_from_signature, _fix_compat_issue29
def wrapper(func):
declared_args = getattr(func, ATTR_ARGS, [])
for a in list(_get_args_from_signature(func)):
declared_args.insert(0, dict(option_strings=a['option_strings'], help="(default: %(default)s)"))
setattr(func, ATTR_ARGS, declared_args)
_fix_compat_issue29(func)
return func
return wrapper
这里的关键点是for
循环注意所有参数都得到相应的help=“%(default)s”
选项。
连同更改argh/constants.py
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
pass
PARSER_FORMATTER = CustomFormatter
我们现在可以方便地使用
@arg_custom()
def func(foo=1, bar=True):
"""Sample function.
Parameters:
foo: float
An example argument.
bar: bool
Another argument.
"""
print foo, bar
argh.dispatch_command(func)
终于屈服了
usage: script.py [-h] [-f FOO] [-b]
Sample function.
Parameters:
foo: float
An example argument.
bar: bool
Another argument.
optional arguments:
-h, --help show this help message and exit
-f FOO, --foo FOO (default: 1)
-b, --bar (default: True)
使用-h
选项执行脚本时。
答案 2 :(得分:0)
关于在帮助行中获取默认值的问题,此argparse
脚本组合了2个格式化程序类
import argparse
def func(foo=1, bar=True):
...
"""
print foo, bar
class MyFormatter(argparse.RawDescriptionHelpFormatter,
argparse.ArgumentDefaultsHelpFormatter):
pass
parser = argparse.ArgumentParser(prog='script.py',
description=func.__doc__,
formatter_class=MyFormatter)
parser.add_argument('-f', '--foo', type=float, default=1, help='test')
parser.add_argument('-b', '--bar', action='store_false', help='test')
parser.print_help()
制造
usage: script.py [-h] [-f FOO] [-b]
Sample function.
...
optional arguments:
-h, --help show this help message and exit
-f FOO, --foo FOO test (default: 1)
-b, --bar test (default: True)
要获取帮助热线中的默认值,我必须在原始帮助热线中包含一些文字(此处为' test')。
在argh
中,您可能必须使用注释来为其提供帮助文字。
如果您正在使用注释,请使用$(default)s
:
parser = argparse.ArgumentParser(prog='script.py',
description=func.__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-f', '--foo', type=float, default=1, help='default: %(default)s')
parser.add_argument('-b', '--bar', action='store_false', help='default: %(default)s')
答案 3 :(得分:0)
感谢您对Argh图书馆的关注。这里讨论的解决方案将纳入下一个版本(argh≥0.25)。另请参阅issue #64(已修复)。