使为任何函数、方法或类方法创建命令行接口变得容易。

parse_this的Python项目详细描述


用法

parse_this 包含创建命令行界面的简单方法 从全班同学那里。为此,您需要使用 parse\u类 类装饰器。

# script.pyfrom__future__importprint_functionfromparse_thisimportSelf,create_parser,parse_class@parse_class()classParseMePlease(object):"""This will be the description of the parser."""@create_parser(Self,int)def__init__(self,foo,ham=1):"""Get ready to be parsed!

        Args:
          foo: because naming stuff is hard
          ham: ham is good and it defaults to 1
        """self._foo=fooself._ham=ham@create_parser(Self,int,int)defdo_stuff(self,bar,spam=1):"""Can do incredible stuff with bar and spam.

        Args:
          bar: as in foobar, will be multiplied with everything else
          spam: goes well with eggs, spam, bacon, spam, sausage and spam

        Returns:
          Everything multiplied with each others
        """returnself._foo*self._ham*bar*spamif__name__=="__main__":print(ParseMePlease.parser.call())
python script.py --help # Print a comprehensive help and usage message
python script.py 2do-stuff 2
>>> 4
python script.py 2 --ham 2do-stuff 2 --spam 2
>>> 16

它如何工作 tl;dr版本

  • 您需要从 使用 创建解析器的命令行
  • 方法参数和关键字参数将是 脚本命令行的参数和选项 参数和选项
  • 其他方法将转换为子命令,再次映射 方法自身参数的命令行参数和选项
  • 你要做到这一点只需:
  • 用parse类装饰您的类
  • create_parser修饰方法 关于争论。使用 self 指定 self 参数
  • 用正确格式的docstring记录类和方法 帮助和使用信息
  • 调用 <;yourclass>;.parser.call() 就完成了!

如果你觉得你可能需要更多的定制和细节,请 继续阅读!

  • 如果修饰了 \uu init\uu 方法,则将其视为 首先,或者是顶层的解析器这意味着 \uu init\uu 将是调用脚本后立即传递的参数 即 python script.py init_arg_1 init_arg_2 等。
  • 顶级解析器的描述取自 docstring或被关键字参数覆盖 解析类
  • create_parser 修饰的每个方法都将成为 它自己的。子parser的命令名与方法相同 名称替换为 - 。"private"方法,其名称 从 \u 开始,默认情况下没有子parser,如下所示 会让他们暴露在外面。但是如果你想暴露他们 可以在中设置关键字参数parse_private=true 解析类 。如果公开,则其命令名将不包含 前导 - 因为这对于命令解析来说会很混乱。特殊的 方法,例如 \uu str\uu ,也可以被修饰。他们的命令 名称将从所有的 \u s中删除,导致命令名如下 如str
  • 当在 parse_类中使用时 取一个额外的参数 name 作为 子命令名。同样的修改s表示 名称 用 -
  • 当调用python script.py时 将显示每个 分析器,以便更容易找到 寻找

参数和类型

parse this和create parser都需要一个类型列表 参数将转换为。可以使用任何python标准类型, 两个特殊值分别用于 self cls 自我 。不需要为关键字提供类型 因为它是从参数的默认值推断出来的。如果 您的方法签名包含 arg_,默认值为12 parse_this 期望 int 其中 arg_with_default 是。

如果这是 test.py 的容器:

from__future__importprint_functionfromparse_thisimportcreate_parser,SelfclassINeedParsing(object):"""A class that clearly needs argument parsing!"""def__init__(self,an_argument):self._an_arg=an_argument@create_parser(Self,int,str,params_delim="--")defparse_me_if_you_can(self,an_int,a_string,an_other_int=12):"""I dare you to parse me !!!

        Args:
            an_int -- int are pretty cool
            a_string -- string aren't that nice
            an_other_int -- guess what? I got a default value
        """returna_string*an_int,an_other_int*self._an_argif__name__=="__main__":need_parsing=INeedParsing(2)print(INeedParsing.parse_me_if_you_can.parser.call(need_parsing))

下面是命令行的输出 python test.py --帮助

usage: test.py [-h][--an_other_int AN_OTHER_INT] an_int a_string

I dare you to parse me !!!

positional arguments:
  an_int             int are pretty cool
  a_string           string aren't that nice

optional arguments:
  -h, --help         show this help message and exit
  --an_other_int AN_OTHER_INT  guess what? I got a default value

如果您可以期望名称的 int an_int ,a str 的名称 a_string 和其他 int 的 名称 an_other_int 和默认值12。解析器也是 !!!!如 --help命令所示。

注意: 创建解析器 不能修饰 类,除非类本身用 parse_class 修饰。一 如果尝试使用 调用,将引发parseThisError 这种分析器的方法。

下面是命令行的输出 python test.py 2 yes --默认值 4

('yesyes', 8)

帮助消息

以便从方法自动生成帮助消息 docstring它需要采用下面描述的特定格式:

...@create_parser(Self,int,int,params_delim=<delimiter_chars>)defmethod(self,spam,ham):"""<description>
    <blank_line>
    <arg_name><delimiter_chars><arg_help>
    <arg_name><delimiter_chars><arg_help>
    """pass...
  • 描述:是用于 命令行
  • 每行参数帮助都有以下组件:
  • arg_name:与方法的参数相同的名称。
  • 分隔符:分隔参数和 它的帮助信息。不建议尽可能使用空白 对多行帮助消息有预期的行为。
  • arg_help:分隔符字符后面的所有内容是否都在下一个字符之前 参数, 空行 或docstring的结尾。

分隔符可以传递给parse this和 创建语法分析器 作为关键字参数 参数 。默认值 因为这是我最常使用的惯例。

如果未指定docstring,则会显示一条通用的-不太有用的-帮助消息 将为命令行和参数生成。

使用none作为默认值,bool作为标志

在python中,使用 none 作为默认值是常见的做法,但是 解析这个 创建解析器 以正常工作 需要指定默认为 none 的参数。否则,A 将引发parseThiserror

...@create_parser(str):deffunction(ham,spam=None):ifspamisnotNone:returnham*spamreturnham# Will raise ParseThisError: To use default value of 'None' you need to specify the type of the argument 'spam' for the method 'function'...

但是指定 spam的类型将允许 创建解析器 工作 正确的

...@create_parser(str,int)deffunction(ham,spam=None):ifspamisnotNone:returnham*spamreturnham# Calling function.parser.call(args="yes".split()) -> 'yes'# Calling function.parser.call(args="yes --spam 3".split()) -> 'yesyesyes'...

另一种常见的做法是使用 bool s作为标志或开关。所有 类型为 bool 的参数,类型为direclty或从 默认值,将成为命令行的可选参数。一 bool 没有默认值的参数将默认为 true 以下示例:

...@create_parser(str,bool)deffunction(ham,spam):ifspam:returnham,spamreturnham# Calling function.parser.call(args="yes".split()) -> 'yes', True# Calling function.parser.call(args="yes --spam".split()) -> 'yes'...

--spam添加到参数将充当标志/开关设置 垃圾邮件 错误 。注意 垃圾邮件 是可选的 给定值 true>如果 --spam不在 解析.< /P>

具有布尔默认值的参数的作用方式相同,即 用作更改默认值的标志:

# script.pyfrom__future__importprint_functionfromparse_thisimportSelf,create_parser,parse_class@parse_class()classParseMePlease(object):"""This will be the description of the parser."""@create_parser(Self,int)def__init__(self,foo,ham=1):"""Get ready to be parsed!

        Args:
          foo: because naming stuff is hard
          ham: ham is good and it defaults to 1
        """self._foo=fooself._ham=ham@create_parser(Self,int,int)defdo_stuff(self,bar,spam=1):"""Can do incredible stuff with bar and spam.

        Args:
          bar: as in foobar, will be multiplied with everything else
          spam: goes well with eggs, spam, bacon, spam, sausage and spam

        Returns:
          Everything multiplied with each others
        """returnself._foo*self._ham*bar*spamif__name__=="__main__":print(ParseMePlease.parser.call())
0

这里一切都按预期工作, spam 的默认值是 false 并将 --spam作为要解析的参数传递 它 是真的

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
手机上的html调试Java web应用程序   Java当前日期和过去日期之间的差值,以年、月、日、小时、分、秒为单位   如果方法名称相同,java如何使扩展类不从上面的类触发方法?   即使在提供了准确的firebase引用之后,java仍出现“无法跳转到类型”异常。请看详情   jar文件中的java图像   java如何避免从缓存读取时修改相同的对象实例?   Android中java完全控制的线程队列   JTextArea中的java计算   java如何独立运行。jar作为64位mashine上的32位   java在尝试实例化自引用泛型类的实例时,如何处理自引用类型参数   java如何安装着色jar而不是原来的jar   java在resultSet之后使用If-Else   多线程是java。朗,反思一下。方法调用线程安全   java 7语言向后兼容性   Objective C中的Category和Java 8中的Default方法是否等效?