Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python’;s argh库:在帮助消息中保留docstring格式_Python_Argparse_Argh - Fatal编程技术网

Python’;s argh库:在帮助消息中保留docstring格式

Python’;s argh库:在帮助消息中保留docstring格式,python,argparse,argh,Python,Argparse,Argh,在寻找更快的方法来解析脚本中的命令行参数时,我遇到了以下问题 我真的很喜欢argh的功能,但我遇到了一个阻碍我使用它的缺点,这与调用-help选项时显示的默认帮助消息有关: 默认情况下,函数的docstring显示在参数列表的顶部。这很好,但是初始格式丢失了。例如,请参见以下示例脚本 import argh def func(foo=1, bar=True): """Sample function. Parameters: foo: float

在寻找更快的方法来解析脚本中的命令行参数时,我遇到了以下问题

我真的很喜欢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

我不希望使用注释来定义参数帮助消息,因为这需要我在每次有需要更改的内容时同时更改函数的docstring和帮助文本

我不熟悉
argh
,但显然它是
argparse
的包装器。我的猜测是,它接受了您的函数
\uuuu doc\uuuu
,并使其成为解析器的
描述
,例如

parser = argparse.ArgumentParser(description=func.__doc__)

argparse
有一个按原样显示描述的
rawscriptionhelpformatter

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)
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
        pass
PARSER_FORMATTER = CustomFormatter
因此,您可以设置:

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)
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

关于在帮助行中获取默认值的问题,这个
argparse
脚本结合了两个格式化程序类

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
中,您可能必须使用注释为其提供帮助文本

如果您使用的是注释,那么可以为其提供带有
$(默认)s
的帮助行:


在@hpaulj的帮助下,我终于获得了想要的行为。为了实现这一点,我定义了一个类似于argh.arg的自定义修饰符,目标是不必为每个参数分别编写
@argh.arg('-param',help=“%(默认)s”)
,而是在我的函数上只使用一个
@arg_custom()
修饰符:

def raw_dispatch_command(function, *args, **kwargs):
    ...
    parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
    set_default_command(parser, function)
    dispatch(parser, *args, **kwargs)
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=“%(默认)s”
选项。 同时更改
argh/constants.py中的相应行

def dispatch_command(function, *args, **kwargs):
    ...
    parser = argparse.ArgumentParser(formatter_class=PARSER_FORMATTER)
    set_default_command(parser, function)
    dispatch(parser, *args, **kwargs)
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
选项执行脚本时。

感谢您对Argh库的兴趣。这里讨论的解决方案将包含在下一个版本(argh)中≥ 0.25). 另请参阅(已修复)。

谢谢@hpaulj,这解决了我最初的问题(并立即引出另一个问题),因为将
PARSER\u FORMATTER=argparse.ArgumentDefaultsHelpFormatter
更改为
PARSER\u FORMATTER=argparse.rawsdescriptionHelpFormatter
后,我将无法显示默认值。是否有一种方法可以同时保留这两种格式,即保留格式并查看可选参数旁边的默认值?另外,如果
ArgumentDefaultsHelpFormatter
PARSE_FORMATTER
的默认值,为什么我不在示例的帮助消息中看到
foo=1
bar=True
的值呢?在
constants.py
中,
PARSER\u FORMATTER=argparse.ArgumentDefaultsHelpFormatter
。此格式化程序包括帮助行中的默认值。因此,通过更改,您可以获得一个特性,而失去另一个特性。您可能必须构造自己的格式化程序类才能获得这两个功能。谢谢,遵循其中一个的建议确实可以生成一个从两个格式化程序继承的类,并且应该导致两者的组合。不过,奇怪的是,即使使用原始的
解析器_FORMATTER=argparse.ArgumentDefaultsHelpFormatter
,也没有打印默认值。因为它相当长,我提供了一个单独的答案,在其中我成功地获得了所需的行为。