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

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第三方库


热门话题
具有相同实体的java JPA关系   java创建Jar文件,复制类路径   多线程如何在ProducerConsumer情况下停止Java线程?   java MBTiles文件有大小限制吗?   java组织。springframework。奥姆。冬眠3。HibernateQueryException HibernateTemplate   java是否会调用onDestroy()?   java Android找不到构建工具   java Hibernate联接列错误:找不到具有逻辑名称的列   电子邮件如何从Java通过电子邮件发送pdf   java无法多次更新FireBase数据库子项   Java:通过HTTP传输Zipfile的内容   AlertDialog中的java自定义操作模式   在java中编写异步调用序列的更好方法是什么?   utf 8在Java中将UTF8转换为ISO88591如何将其保持为单字节   java为进度条设置了一个固定值