避免重复记录脚本和函数

时间:2019-02-19 21:30:37

标签: python argparse pep8

在编写脚本时,有时会使用函数来封装脚本的功能。这是因为我可能想从代码中调用该函数或将其作为脚本运行。有什么方法可以避免在argparse中的帮助字符串中重复函数参数的文档说明?例如:

import argparse
def my_function(arg_one, arg_two):
    """
    arg_one: The first argument.
    arg_two: The second argument.
    """
    print("The first argument is %r" % arg_one)
    print("The second argument is %r" % arg_two)

if __name__=="main":
    parser = argparse.ArgumentParser()
    parser.add_argument('--arg-one', help="The first argument.")
    parser.add_argument('--arg-two', help="The second argument.")
    args = parser.parse_args()
    my_function(args.arg_one, args.arg_two)

由于函数和脚本的参数完全对应,因此您可以看到我不得不对它们进行两次记录(“第一个参数”,“第二个参数”)。这是一个琐碎的问题,但确实很烦人。我应该根本不使用任何功能吗?

1 个答案:

答案 0 :(得分:1)

这是我的写法...

""" My Crazy Program
Usage:
    my_prog [options]

Options:
"""

def my_function(file_output, file_input, recursive=False):
    """
    output=str: specifies an output path
    input=str: specifies an input path
    recursive: apply recursively
    """
    print("The first argument is %r" % file_output)
    print("The second argument is %r" % file_input)
    print("The third argument is %r" % recursive)

# This is where the magic happens
__doc__ += '\n'.join(f'   --{parsed[0]: <15}  {parsed[1]}'
                     for parsed in (
                         line.strip().split(': ') 
                         for line in my_function.__doc__.split('\n'))
                     if len(parsed) == 2)

if __name__ == "__main__":
    from docopt import docopt
    ARGS = docopt(__doc__)
    my_function(ARGS['--output'], ARGS['--input'], ARGS['--recursive'])

好吧,您看到了神奇的一句话(从__doc__ += ...开始),它使该模块的文档变成了:

 My Crazy Program
Usage:
    my_prog [options]

Options:
   --output=str       specifies an output path
   --input=str        specifies an input path
   --recursive        apply recursively

然后,docopt解析并返回此字典:

$ python my_prog
{'--input': None,
 '--output': None,
 '--recursive': False}

$ python my_prog --output /dev/null --recursive
{'--input': None,
 '--output': '/dev/null',
 '--recursive': True}

可用于调用该函数并获取结果:

The first argument is '/dev/null'
The second argument is None
The third argument is True

我喜欢这个解决方案,因为它是单行的,但是我会同意你的观点,它不是很漂亮,我将让你编写自己的漂亮函数,该函数自动为每个文件:o)