从python3类型注释自动生成基于单击的clis。

autoclick的Python项目详细描述


自动单击

autoclick使用类型注释创建基于单击的cli。

最简单的autoclick使用要求用@autoclick.command注释主方法

# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
$ python test.py --help
Usage: test.py [OPTIONS][GREETING][NAME]

Options:
  --help  Show this message and exit.

对于其他自定义项,关键字参数可以传递给命令decorator:

importautoclick@autoclick.command(short_names={"greeting":"G","name":"n"},show_defaults=True)defmain(greeting:str="hello",name:str="human"):print(f"{greeting}{name}")
$ python test.py --help
Usage: test.py [OPTIONS]

Options:
  -G, --greeting TEXT  [default: hello]
  -n, --name TEXT      [default: human]
  --help               Show this message and exit.

类型转换

在click中,类型转换可以在回调中完成,也可以使用可调用类型(例如paramtype的子类)作为类型。在autoclick中,根据可调用类型的类型注释自动执行类型转换。但是,对于更复杂的类型转换,还有三种附加方法:

  1. 自动转换功能。转换函数由@conversion修饰。默认情况下,转换修饰符从返回注释推断要转换为的类型。否则,可以将目标类型指定为decorator的参数。decorator将函数注册为指定类型的转换器。当遇到该类型作为命令函数的参数注释时,converter函数用于将字符串参数转换为该类型。
importautoclickclassBork:def__init__(self,n:int):self.n=ndef__str__(self):print(",".join(["bork"]*self.n))@autoclick.conversion()defbork(n:int)->Bork:returnBork(n)@autoclick.command("bork")defmain(b:Bork):print(b)

在需要专门处理公共类型的情况下,可以使用typing.newtype

importautoclickimporttypingDoubleInt=typing.NewType("DoubleInt",int)@autoclick.conversion(DoubleInt)defdouble_int(i:str):returnint(i)*2@autoclick.command("double")defmain(i1:int,i2:DoubleInt):print(i1,i2)
  1. 转换函数也可以在decorator命令中显式指定:
importautoclick@autoclick.command(types={"a":double_int})defmain(a:int):print(a)

请注意,单击中的任何类型。类型包也可以这样使用。

  1. 对于复合类型,可以使用autoclick.composite_typeautoclick.composite_factory函数。复合类型的一个示例是一个类,该类的构造函数需要多个参数。对于复合类型,将执行相同的基于注释的cli创建,并将参数注入cli以代替复合参数。
importautoclick@autoclick.composite_type()classFoo:def__init__(self,bar:str,baz:int):self.bar=barself.baz=baz@autoclick.command()defmain(foo:Foo):print(foo.bar,foo.baz)

在这种情况下,main的选项是--foo bar--foo baz。处理完cli后,这些选项的值将用于构造foo实例,然后将其传递给对main的调用。命令函数中的参数名在复合类型的参数名之前,因此复合类型可以在命令函数签名中使用多个类型。

函数返回一个复杂类型。例如,下面的代码等同于上面的代码:

importautoclickclassFoo:def__init__(self,bar:str,baz:int):...@autoclick.composite_factory(Foo)deffoo_factory(bar:str,baz:int):returnFoo(bar,baz)

条件和验证

条件和验证是相似的-它们都是采用**kwargs参数的装饰符。关键字是参数名,值是参数值。当函数接受多个参数时,它们应该指定顺序;顺序取决于python 3.5+字典隐式排序的行为。

条件函数用于根据其他参数的值修改一个或多个参数的值。条件函数可以返回dict,其中键是应该更新的参数名,值是新的参数值。

验证函数用于检查一个或多个参数值是否符合某些限制。将忽略验证函数的返回值。

条件函数和验证函数都可以抛出validationerror。

这些函数可以通过两种方式与参数关联。首先,使用命令decorator的条件验证参数。这些是dict,参数名或参数名元组是键,函数是值。第二,当参数用@autoclick.validation修饰并且参数类型与validation decora的类型参数匹配时,验证函数可以与参数关联。托尔。多参数验证只能通过第一个方法关联。由于条件应该是多值的,因此没有@autoclick.conditional注释,即必须始终显式指定它们。

类型匹配

您还可以使用typing.newtype函数创建的不同类型进行类型匹配验证。例如,如果要定义的参数必须为正,甚至是:

# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
0

请注意,类型库当前不提供交集类型。因此,正数、偶数和正数even都必须是不同的验证。有两种简化方法:

  1. 将参数添加到命令decorator的validation dict中,并将mutliple函数的元组作为值:
# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
1
  1. 创建复合验证:
# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
2

甚至

# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
3

docstring利用率

autoclick使用docparse库解析命令函数和组合的docstrings以提取帮助文本。请注意,当前DocParse仅支持Google样式的DocStrings。

# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
4
# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
5

通过创建命令组,autoclick clis可以有多个子命令:

# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
6

autoclick提供了可选的组类型。例如,defaultautoclickgroup可以在未指定命令时使用默认命令名来运行:

# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
7

安装

# test.pyimportautoclick@autoclick.command("greet")defmain(greeting:str,name:str):print(f"{greeting}{name}")if__name__=="__main__":main()
8

运行时依赖项

  • 巨蟒3.6+
  • DocParse

生成依赖项

  • 诗歌0.12+
  • pytest(带pytest cov插件)

详细信息

选项属性推断

以下各节详细介绍如何从类型和docstring信息推断单击类/函数的参数:

所有参数

  • name(long):参数name;下划线转换为破折号,除非在命令decorator中保持下划线=true。
  • 名称(短):从参数名称最左边的字符开始,第一个不被其他参数或任何内置参数使用的字符;可以通过在命令装饰器中指定"parameter_names"字典来覆盖。
  • 类型:从类型提示推断;如果缺少类型提示,则从默认值推断;如果缺少默认值,则str.
  • 必需:默认情况下,位置参数(参数)为true,关键字参数(选项)为false;如果命令decorator中的positional_as_options=true,则位置参数为必需选项。可以在命令decorator的"required"列表中指定必需的关键字参数。
  • 默认值:未设置位置参数,关键字参数的关键字值。
  • nargs:1除非type是tuple(在这种情况下,nargs是tuple的参数数)。

仅选项

  • hide_input:false,除非指定了命令"hidden"参数并包含参数名。
  • is_flag:true用于布尔类型的关键字参数;假定为true选项,除非名称以"no"开头;通过添加/删除"no-",将始终推断出另一个选项
  • multiple:对于序列类型为true
  • 帮助:从docstring解析。

待办事项

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

推荐PyPI第三方库


热门话题
阻止在java(或scala)中创建文件   TableView列的java编辑值   java会删除多态性中的额外变量吗?   java Spring数据JpaRepository已批处理。然后保存()。flush()导致重复密钥异常   java OpenGL构造形状的困难   重载的java方法   JAVA中的hmacsha1 hmacsha1   java使用JUnite和JBossIDE   在java中面临输入不匹配异常的一些问题   java图像没有重新绘制,只是相乘   java“mvc:annotationdriven”使程序崩溃   java点击播放按钮,应用程序已停止,再次打开   struts 2中动作变量和列表变量的java检查等于?   java Textarea如何在每次循环迭代后追加文本?   java为什么这个If语句返回True?   C++与java之间的低延时IPC   java不可访问代码,计数器=0   java greendao设置超类