click是一个python包,用于为您的应用程序创建漂亮的命令行界面.我一直在玩点击,今天在github 上推了这个简单的罗马数字转换器.
我现在要做的是测试我的点击应用程序.我正在阅读文档,但不知道如何运行测试.
有没有人有测试点击应用程序的经验?
所以我想要实现的是确保参数是某些预定义集合(这里是tool1,tool2,tool3)的一部分,就像使用@click.option和type=click.Choice(),同时能够传递多个参数,如@click.argumentwith nargs=-1.
import click
@click.command()
@click.option('--tools', type=click.Choice(['tool1', 'tool2', 'tool3']))
@click.argument('programs', nargs=-1)
def chooseTools(programs, tools):
"""Select one or more tools to solve the task"""
# Selection of only one tool, but it is from the predefined set
click.echo("Selected tools with 'tools' are {}".format(tools))
# Selection of multiple tools, but no in-built error handling if not in set
click.echo("Selected tools with 'programs' are {}".format(programs))
Run Code Online (Sandbox Code Playgroud)
这将是这样的例子:
python selectTools.py --tools tool1 tool3 tool2 nonsense
Selected tools with …Run Code Online (Sandbox Code Playgroud) 我正在寻找一些建议,以避免不得不两次实例化一个类;这更多是一个设计模式问题。我正在使用Python Click库创建一个应用程序。
我有一个Settings类,该类首先将所有初始默认设置加载到字典中(硬编码到应用程序中),然后将用户计算机上TOML文件中的所有设置覆盖(如果指定)加载到字典中,然后最后将两者合并并将它们用作类实例(settings.<something>)的属性。
对于大多数这些设置,我还希望能够指定命令行标志。优先级将变为:
为了获得此结果,我发现在使用Click的装饰器时,我必须执行以下操作:
import click
from myapp import Settings
settings = Settings()
pass_settings = click.make_pass_decorator(Settings, ensure=True)
@click.command()
@click.help_option('-h', '--help')
@click.option(
'-s', '--disk-size',
default=settings.instance_disk_size,
help="Disk size",
show_default=True,
type=int
)
@click.option(
'-t', '--disk-type',
default=settings.instance_disk_type,
help="Disk type",
show_default=True,
type=click.Choice(['pd-standard', 'pd-ssd'])
)
@pass_settings
def create(settings, disk_size, disk_type):
print(disk_size)
print(disk_type)
Run Code Online (Sandbox Code Playgroud)
settings = Settings()需要线来提供@click.option与所述装饰default值。该default值可以来自用户替代TOML文件(如果存在),也可以来自应用程序默认值。Settings …我有一个使用单击来获取输入参数的脚本。根据他们的文档,CliRunner 可用于进行单元测试:
import click
from click.testing import CliRunner
def test_hello_world():
@click.command()
@click.argument('name')
def hello(name):
click.echo('Hello %s!' % name)
runner = CliRunner()
result = runner.invoke(hello, ['Peter'])
assert result.exit_code == 0
assert result.output == 'Hello Peter!\n'
Run Code Online (Sandbox Code Playgroud)
这是针对在测试中内联编写的小型 hello-world 函数完成的。我的问题是:
如何对不同文件中的脚本执行相同的测试?
使用 click 的脚本示例:
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name', help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo('Hello %s!' % name) …Run Code Online (Sandbox Code Playgroud) 我正在尝试装饰一个已经由@click命令行装饰和调用的函数。
大写输入的正常装饰可能如下所示:
标准装饰.py
def capitalise_input(f):
def wrapper(*args):
args = (args[0].upper(),)
f(*args)
return wrapper
@capitalise_input
def print_something(name):
print(name)
if __name__ == '__main__':
print_something("Hello")
Run Code Online (Sandbox Code Playgroud)
然后从命令行:
$ python standard_decoration.py
HELLO
Run Code Online (Sandbox Code Playgroud)
单击文档中的第一个示例如下所示:
你好.py
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo('Hello %s!' % name)
if __name__ == '__main__':
hello()
Run Code Online (Sandbox Code Playgroud)
从命令行运行时:
$ python hello.py --count=3
Your …Run Code Online (Sandbox Code Playgroud) python command-line-arguments python-3.x python-decorators python-click
默认情况下,我的脚本在没有提供参数时不显示任何内容duh.py:
import click
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
@click.command(context_settings=CONTEXT_SETTINGS)
@click.option('--toduhornot', is_flag=True, help='prints "duh..."')
def duh(toduhornot):
if toduhornot:
click.echo('duh...')
if __name__ == '__main__':
duh()
Run Code Online (Sandbox Code Playgroud)
$ python3 test_click.py -h
Usage: test_click.py [OPTIONS]
Options:
--toduhornot prints "duh..."
-h, --help Show this message and exit.
$ python3 test_click.py --toduhornot
duh...
$ python3 test_click.py
Run Code Online (Sandbox Code Playgroud)
如上图,默认不打印信息python3 test_click.py。
有没有办法,-h如果没有给出参数,则默认选项设置为,例如
$ python3 test_click.py
Usage: test_click.py [OPTIONS]
Options:
--toduhornot prints "duh..."
-h, --help Show this message and exit.
Run Code Online (Sandbox Code Playgroud) 我想要一个命令行工具,其用法如下:
$ program <arg> does something, no command name required
$ program cut <arg>
$ program eat <arg>
Run Code Online (Sandbox Code Playgroud)
Click 代码如下所示:
@click.group()
def main() :
pass
@main.command()
@click.argument('arg')
def noname(arg) :
# does stuff
@main.command()
@click.argument('arg')
def cut(arg) :
# cuts stuff
@main.command()
@click.argument('arg')
def eat(arg) :
# eats stuff
Run Code Online (Sandbox Code Playgroud)
我的问题是,对于这段代码,总是有一个必需的命令名称,即:我需要运行$ program noname arg. 但我希望能够运行$ program arg.
这个问题是关于click包的:我想设置我的命令,以便某些命令optional options依赖于特定的选项值,并且根据其值需要。
所需选项:
子选项: 如果是
1然后选项 generator_string应该变成required=True2然后选项 number_of_sample_points应该变成required=True3然后选项 number_of_center_points应该变成required=True有效示例:
--input ./input.txt --doe 1 --generator_string 1234--input ./input.txt --doe 2 --number_of_sample_points 3--input ./input.txt --doe 3 --number_of_center_points 2代码:
import click
def check_output(ctx, param, value):
if value == 1:
if not ctx.params['generator_string']:
setOptionAsRequired(ctx, 'generator_string')
return value
def setOptionAsRequired(ctx, name):
for p in ctx.command.params:
if isinstance(p, click.Option) and …Run Code Online (Sandbox Code Playgroud) 我正在为我的 Python 应用程序添加 CLI。CLI 应允许一次运行多个命令。命令应该有公共选项和个人选项。
例子:
$ python mycliapp.py --common-option1 value1 --common-option2 value2 cmd1 --cmd1-option cmd2 --cmd2-option somevalue cmd3
Run Code Online (Sandbox Code Playgroud)
该示例有两个所有命令都使用的公共选项,并且每个命令可以有或没有仅该命令使用的选项。
我考虑过Python Click。它具有丰富的功能,但它不允许(至少我没有发现)在没有一些主命令的情况下使用常用选项。
使用 Click 时,上面的示例将如下所示:
$ python mycliapp.py maincmd --common-option1 value1 --common-option2 value2 cmd1 --cmd1-option cmd2 --cmd2-option somevalue cmd3
Run Code Online (Sandbox Code Playgroud)
另外,还考虑了 Python Argparse。看起来它可以满足我的需要,并且我已经成功编写了一个代码,该代码可以使用常见选项和单个命令,但无法使用多个命令。此页面Python argparse - Add argument to multiple subparsers有很好的示例,但似乎 command2 应该是 command1 的子命令。它有点不同,因为我需要命令可以按任何顺序执行。
我使用 click 来解析命令行参数https://click.palletsprojects.com/en/7.x/
import click
@click.option('-n', '--name', required=True, type=str, help='...')
def create(name: str):
Run Code Online (Sandbox Code Playgroud)
我想使用正则表达式来确保名称与特定模式匹配。如何使用点击来做到这一点?