选项¶
向命令添加选项可以通过 option()
装饰者。因为选项可以有不同的版本,所以有大量的参数来配置它们的行为。click中的选项与 positional arguments .
为你的选择命名¶
选项的名称在调用修饰函数时将用作Python参数名。这可以从选项名称中推断出来,也可以显式给出。名称作为装饰器的位置参数。
按以下顺序选择名称
如果名称没有加前缀,则它将用作Python参数名,而不会在命令行中将其视为选项名。
如果至少有一个名称以两个破折号为前缀,则使用给定的第一个名称作为名称。
以一个破折号为前缀的名字在其他情况下使用。
要获取Python参数名,所选名称将转换为小写,最多删除两个破折号作为前缀,其他短划线转换为下划线。
@click.command()
@click.option('-s', '--string-to-echo')
def echo(string_to_echo):
click.echo(string_to_echo)
@click.command()
@click.option('-s', '--string-to-echo', 'string')
def echo(string):
click.echo(string)
"-f", "--foo-bar"
, the name isfoo_bar
"-x"
, the name isx
"-f", "--filename", "dest"
, the name isdest
"--CamelCase"
, the name iscamelcase
"-f", "-fb"
, the name isf
"--f", "--foo-bar"
, the name isf
"---f"
, the name is_f
基本值选项¶
最基本的选项是值选项。这些选项接受一个值参数。如果未提供类型,则使用默认值的类型。如果没有提供默认值,则假定类型为 STRING
. 除非显式指定了名称,否则参数的名称是定义的第一个长选项;否则将使用第一个短选项。默认情况下,不需要选项,但是要使选项成为必需的,只需传入 required=True 作为修饰符的参数。
@click.command()
@click.option('--n', default=1)
def dots(n):
click.echo('.' * n)
# How to make an option required
@click.command()
@click.option('--n', required=True, type=int)
def dots(n):
click.echo('.' * n)
# How to use a Python reserved word such as `from` as a parameter
@click.command()
@click.option('--from', '-f', 'from_')
@click.option('--to', '-t')
def reserved_param_name(from_, to):
click.echo(f"from {from_} to {to}")
在命令行上:
$ dots --n=2
..
在这种情况下,选项的类型为 INT
因为默认值是一个整数。
要在显示命令帮助时显示默认值,请使用 show_default=True
@click.command()
@click.option('--n', default=1, show_default=True)
def dots(n):
click.echo('.' * n)
$ dots --help
Usage: dots [OPTIONS]
Options:
--n INTEGER [default: 1]
--help Show this message and exit.
对于单选项布尔标志,如果缺省值为FALSE,则默认为隐藏。
@click.command()
@click.option('--n', default=1, show_default=True)
@click.option("--gr", is_flag=True, show_default=True, default=False, help="Greet the world.")
@click.option("--br", is_flag=True, show_default=True, default=True, help="Add a thematic break")
def dots(n, gr, br):
if gr:
click.echo('Hello world!')
click.echo('.' * n)
if br:
click.echo('-' * n)
$ dots --help
Usage: dots [OPTIONS]
Options:
--n INTEGER [default: 1]
--gr Greet the world.
--br Add a thematic break [default: True]
--help Show this message and exit.
多值选项¶
有时,你可以选择多个论点。对于选项,只支持固定数量的参数。这可以通过 nargs
参数。这些值随后存储为一个元组。
@click.command()
@click.option('--pos', nargs=2, type=float)
def findme(pos):
a, b = pos
click.echo(f"{a} / {b}")
在命令行上:
$ findme --pos 2.0 3.0
2.0 / 3.0
元组作为多值选项¶
Changelog
在 4.0 版本加入.
你可以通过使用 nargs 设置为特定的数字,结果元组中的每个项都属于同一类型。这可能不是你想要的。通常,您可能希望对元组中的不同索引使用不同的类型。为此,可以直接将元组指定为类型:
@click.command()
@click.option('--item', type=(str, int))
def putitem(item):
name, id = item
click.echo(f"name={name} id={id}")
在命令行上:
$ putitem --item peter 1338
name=peter id=1338
通过使用tuple文本作为类型, nargs 自动设置为元组的长度和 click.Tuple
类型将自动使用。因此,上述示例等效于:
@click.command()
@click.option('--item', nargs=2, type=click.Tuple([str, int]))
def putitem(item):
name, id = item
click.echo(f"name={name} id={id}")
多种选择方案¶
类似于 nargs
,还有一种情况是,希望支持一个参数被多次提供并记录所有值,而不仅仅是最后一个。例如, git commit -m foo -m bar
将为提交消息记录两行: foo
和 bar
. 这可以通过 multiple
旗帜:
例子:
@click.command()
@click.option('--message', '-m', multiple=True)
def commit(message):
click.echo('\n'.join(message))
在命令行上:
$ commit -m foo -m bar
foo
bar
当通过 default
具有 multiple=True
,默认值必须是列表或元组,否则将被解释为单个字符的列表。
@click.option("--format", multiple=True, default=["json"])
计数¶
在一些非常罕见的情况下,使用选项的重复来向上计数整数是很有趣的。这可用于详细标志,例如:
@click.command()
@click.option('-v', '--verbose', count=True)
def log(verbose):
click.echo(f"Verbosity: {verbose}")
在命令行上:
$ log -vvv
Verbosity: 3
布尔标志¶
布尔标志是可以启用或禁用的选项。这可以通过一次定义两个用斜线分隔的标志来实现。 (/
)用于启用或禁用选项。(如果斜线在选项字符串中,则Click自动知道它是布尔标志,并将通过 is_flag=True
隐式。)Click始终希望您提供启用和禁用标志,以便以后更改默认值。
例子:
import sys
@click.command()
@click.option('--shout/--no-shout', default=False)
def info(shout):
rv = sys.platform
if shout:
rv = rv.upper() + '!!!!111'
click.echo(rv)
在命令行上:
$ info --shout
LINUX!!!!111
$ info --no-shout
linux
$ info
linux
如果您真的不想关闭开关,您只需定义一个开关并手动通知Click某个东西是一个标志:
import sys
@click.command()
@click.option('--shout', is_flag=True)
def info(shout):
rv = sys.platform
if shout:
rv = rv.upper() + '!!!!111'
click.echo(rv)
在命令行上:
$ info --shout
LINUX!!!!111
$ info
linux
请注意,如果选项中已经包含斜线(例如,如果使用Windows样式参数 /
是前缀字符),您也可以通过 ;
而是:
@click.command()
@click.option('/debug;/no-debug')
def log(debug):
click.echo(f"debug={debug}")
if __name__ == '__main__':
log()
Changelog
在 6.0 版本发生变更.
如果只想为第二个选项定义别名,则需要使用前导空格来消除格式字符串的歧义:
例子:
import sys
@click.command()
@click.option('--shout/--no-shout', ' /-S', default=False)
def info(shout):
rv = sys.platform
if shout:
rv = rv.upper() + '!!!!111'
click.echo(rv)
$ info --help
Usage: info [OPTIONS]
Options:
--shout / -S, --no-shout
--help Show this message and exit.
功能开关¶
除了布尔标记之外,还有一些功能开关。通过将多个选项设置为相同的参数名并定义标志值来实现这些功能。请注意,通过提供 flag_value
参数,Click将隐式设置 is_flag=True
.
要设置默认标志,请指定 True 设置为默认标志。
import sys
@click.command()
@click.option('--upper', 'transformation', flag_value='upper',
default=True)
@click.option('--lower', 'transformation', flag_value='lower')
def info(transformation):
click.echo(getattr(sys.platform, transformation)())
在命令行上:
$ info --upper
LINUX
$ info --lower
linux
$ info
LINUX
选择选项¶
有时,您希望让一个参数成为一个值列表的选项。在这种情况下,你可以使用 Choice
类型。它可以用有效值列表实例化。将返回最初传递的选项,而不是在命令行上传递的str。令牌规范化函数和 case_sensitive=False
可能导致两者不同,但仍然匹配。
例子:
@click.command()
@click.option('--hash-type',
type=click.Choice(['MD5', 'SHA1'], case_sensitive=False))
def digest(hash_type):
click.echo(hash_type)
它是什么样子的:
$ digest --hash-type=MD5
MD5
$ digest --hash-type=md5
MD5
$ digest --hash-type=foo
Usage: digest [OPTIONS]
Try 'digest --help' for help.
Error: Invalid value for '--hash-type': 'foo' is not one of 'MD5', 'SHA1'.
$ digest --help
Usage: digest [OPTIONS]
Options:
--hash-type [MD5|SHA1]
--help Show this message and exit.
只将选项作为列表或元组传递。其他ITerable(如生成器)可能会导致意外结果。
选项与具有 multiple=True
. 如果A default
值用 multiple=True
,它应该是有效选择的列表或元组。
在考虑到 case_sensitive
以及任何指定的令牌规范化函数。
Changelog
在 7.1 版本发生变更: 选项的结果值将始终是最初传递的选项之一,而不管 case_sensitive
.
提示¶
在某些情况下,您需要可以从命令行提供的参数,但如果没有提供,则请求用户输入。这可以通过定义提示字符串通过Click来实现。
例子:
@click.command()
@click.option('--name', prompt=True)
def hello(name):
click.echo(f"Hello {name}!")
看起来像是:
$ hello --name=John
Hello John!
$ hello
Name: John
Hello John!
如果您对默认提示字符串不满意,可以请求其他提示字符串:
@click.command()
@click.option('--name', prompt='Your name please')
def hello(name):
click.echo(f"Hello {name}!")
它是什么样子的:
$ hello
Your name please: John
Hello John!
建议不要将prompt与设置为True的multiple标志一起使用。相反,在函数中以交互方式提示。
默认情况下,如果没有通过命令行传递输入,则会提示用户输入。要关闭此行为,请参见 可选值 .
密码提示¶
Click还支持隐藏提示和请求确认。这对于输入密码很有用:
import codecs
@click.command()
@click.option(
"--password", prompt=True, hide_input=True,
confirmation_prompt=True
)
def encode(password):
click.echo(f"encoded: {codecs.encode(password, 'rot13')}")
$ encode
Password:
Repeat for confirmation:
encoded: frperg
因为这种参数组合非常常见,所以也可以用 password_option()
装饰者:
@click.command()
@click.password_option()
def encrypt(password):
click.echo(f"encoded: to {codecs.encode(password, 'rot13')}")
提示的动态默认值¶
这个 auto_envvar_prefix
和 default_map
上下文选项允许程序从环境或配置文件中读取选项值。但是,这会覆盖提示机制,这样用户就不能选择以交互方式更改值。
如果要让用户配置默认值,但在命令行上未指定该选项时仍会提示用户,则可以通过提供一个Callable作为默认值来进行配置。例如,要从环境中获取默认值,请执行以下操作:
import os
@click.command()
@click.option(
"--username", prompt=True,
default=lambda: os.environ.get("USER", "")
)
def hello(username):
click.echo(f"Hello, {username}!")
要描述默认值是什么,请在 show_default
.
import os
@click.command()
@click.option(
"--username", prompt=True,
default=lambda: os.environ.get("USER", ""),
show_default="current user"
)
def hello(username):
click.echo(f"Hello, {username}!")
$ hello --help
Usage: hello [OPTIONS]
Options:
--username TEXT [default: (current user)]
--help Show this message and exit.
回拨和热切的选择¶
有时,您需要一个参数来完全更改执行流。例如,当您希望 --version
打印出版本然后退出应用程序的参数。
注:A的实际实现 --version
可重复使用的参数在click as中可用 click.version_option()
. 这里的代码只是如何实现这样一个标志的示例。
在这种情况下,您需要两个概念:一个是热切参数,另一个是回调。热切参数是在其他参数之前处理的参数,而回调是在处理参数之后执行的参数。迫切性是必要的,这样较早的必需参数就不会产生错误消息。例如,如果 --version
不急,是个参数 --foo
以前是必需的和定义的,您需要为其指定 --version
工作。有关详细信息,请参阅 回调评估顺序 .
回调是使用三个参数调用的函数:当前 Context
,洋流 Parameter
和价值。上下文提供了一些有用的功能,比如退出应用程序,并允许访问其他已经处理过的参数。
下面是一个示例, --version
标志:
def print_version(ctx, param, value):
if not value or ctx.resilient_parsing:
return
click.echo('Version 1.0')
ctx.exit()
@click.command()
@click.option('--version', is_flag=True, callback=print_version,
expose_value=False, is_eager=True)
def hello():
click.echo('Hello World!')
这个 expose_value 参数防止了非常无意义的 version
参数从传递到回调。如果未指定,则将向 hello 脚本。这个 resilient_parsing 如果click想要解析命令行而没有任何破坏性行为会改变执行流,则会将标志应用于上下文。在这种情况下,因为我们将退出程序,所以我们什么也不做。
它是什么样子的:
$ hello
Hello World!
$ hello --version
Version 1.0
是参数¶
对于危险的操作,能够请求用户确认是非常有用的。这可以通过添加一个布尔值来完成。 --yes
标记并请求确认用户是否未提供并在回调中失败:
def abort_if_false(ctx, param, value):
if not value:
ctx.abort()
@click.command()
@click.option('--yes', is_flag=True, callback=abort_if_false,
expose_value=False,
prompt='Are you sure you want to drop the db?')
def dropdb():
click.echo('Dropped all tables!')
以及命令行上的外观:
$ dropdb
Are you sure you want to drop the db? [y/N]: n
Aborted!
$ dropdb --yes
Dropped all tables!
因为这种参数组合非常常见,所以也可以用 confirmation_option()
装饰者:
@click.command()
@click.confirmation_option(prompt='Are you sure you want to drop the db?')
def dropdb():
click.echo('Dropped all tables!')
来自环境变量的值¶
click的一个非常有用的特性是除了常规参数之外,还可以接受来自环境变量的参数。这使得工具的自动化更加容易。例如,您可能希望传递一个配置文件, --config
参数,也支持导出 TOOL_CONFIG=hello.cfg
关键价值对,以获得更好的发展经验。
点击有两种方式支持这一点。一种方法是自动构建环境变量,而环境变量只支持选项。要启用此功能,请 auto_envvar_prefix
需要将参数传递给调用的脚本。然后将每个命令和参数添加为大写下划线分隔变量。如果有一个子命令调用 run
接受一个被称为 reload
前缀是 WEB
,那么变量是 WEB_RUN_RELOAD
.
示例用法:
@click.command()
@click.option('--username')
def greet(username):
click.echo(f'Hello {username}!')
if __name__ == '__main__':
greet(auto_envvar_prefix='GREETER')
从命令行:
$ export GREETER_USERNAME=john
$ greet
Hello john!
使用时 auto_envvar_prefix
对于命令组,命令名需要包含在环境变量中,在前缀和参数名之间, i.e. PREFIX_COMMAND_VARIABLE
. 如果有一个名为 run-server
接受一个被称为 host
前缀是 WEB
,那么变量是 WEB_RUN_SERVER_HOST
.
例子:
@click.group()
@click.option('--debug/--no-debug')
def cli(debug):
click.echo(f"Debug mode is {'on' if debug else 'off'}")
@cli.command()
@click.option('--username')
def greet(username):
click.echo(f"Hello {username}!")
if __name__ == '__main__':
cli(auto_envvar_prefix='GREETER')
$ export GREETER_DEBUG=false
$ export GREETER_GREET_USERNAME=John
$ cli greet
Debug mode is off
Hello John!
第二个选项是通过在选项上定义环境变量的名称,从特定的环境变量中手动拉入值。
示例用法:
@click.command()
@click.option('--username', envvar='USERNAME')
def greet(username):
click.echo(f"Hello {username}!")
if __name__ == '__main__':
greet()
从命令行:
$ export USERNAME=john
$ greet
Hello john!
在这种情况下,它也可以是选择第一个环境变量的不同环境变量的列表。
环境值中的多个值¶
由于选项可以接受多个值,从环境变量(字符串)中拉入这些值要复杂一些。Click解决此问题的方法是将其保留为自定义此行为的类型。对于两者 multiple
和 nargs
值不是 1
,Click将调用 ParamType.split_envvar_value()
执行拆分的方法。
所有类型的默认实现是在空白处拆分。此规则的例外是 File
和 Path
根据操作系统的路径拆分规则拆分的类型。在Linux和OS X这样的UNIX系统上,每个冒号上都会发生拆分。 (:
,对于Windows,在每个分号上 (;
)
示例用法:
@click.command()
@click.option('paths', '--path', envvar='PATHS', multiple=True,
type=click.Path())
def perform(paths):
for path in paths:
click.echo(path)
if __name__ == '__main__':
perform()
从命令行:
$ export PATHS=./foo/bar:./test
$ perform
./foo/bar
./test
其他前缀字符¶
Click可以处理除 -
供选择。例如,如果您想将斜线作为参数处理,这很有用 /
或者类似的东西。注意,一般情况下,这是非常不鼓励的,因为click希望开发人员保持接近POSIX语义。但是,在某些情况下,这是有用的:
@click.command()
@click.option('+w/-w')
def chmod(w):
click.echo(f"writable={w}")
if __name__ == '__main__':
chmod()
从命令行:
$ chmod +w
writable=True
$ chmod -w
writable=False
请注意,如果您正在使用 /
作为前缀字符,如果要使用布尔标记,则需要使用 ;
而不是 /
:
@click.command()
@click.option('/debug;/no-debug')
def log(debug):
click.echo(f"debug={debug}")
if __name__ == '__main__':
log()
范围选项¶
这个 IntRange
类型扩展 INT
类型以确保该值包含在给定范围内。这个 FloatRange
类型对 FLOAT
.
如果 min
或 max
省略了,那一边是 无边界 . 该方向上的任何值都可以接受。默认情况下,两个边界都是 关闭 ,即边界值包含在可接受范围内。 min_open
和 max_open
可用于从该范围排除的范围。
如果 clamp
模式启用时,范围之外的值将设置为边界,而不是失败。例如,范围 0, 5
会回来 5
为了价值 10
或 0
为了价值 -1
. 使用时 FloatRange
, clamp
仅当两个边界都为 关闭 (默认值)。
@click.command()
@click.option("--count", type=click.IntRange(0, 20, clamp=True))
@click.option("--digit", type=click.IntRange(0, 9))
def repeat(count, digit):
click.echo(str(digit) * count)
$ repeat --count=100 --digit=5
55555555555555555555
$ repeat --count=6 --digit=12
Usage: repeat [OPTIONS]
Try 'repeat --help' for help.
Error: Invalid value for '--digit': 12 is not in the range 0<=x<=9.
用于验证的回调¶
Changelog
在 2.0 版本发生变更.
如果要应用自定义验证逻辑,可以在参数回调中执行此操作。如果验证不起作用,这些回调既可以修改值,也可以引发错误。回调在类型转换之后运行。它被调用用于所有来源,包括提示。
在Click 1.0中,只能提升 UsageError
但从click 2.0开始,您还可以提高 BadParameter
错误,这有一个额外的优点,即它将自动格式化错误消息以同时包含参数名。
def validate_rolls(ctx, param, value):
if isinstance(value, tuple):
return value
try:
rolls, _, dice = value.partition("d")
return int(dice), int(rolls)
except ValueError:
raise click.BadParameter("format must be 'NdM'")
@click.command()
@click.option(
"--rolls", type=click.UNPROCESSED, callback=validate_rolls,
default="1d6", prompt=True,
)
def roll(rolls):
sides, times = rolls
click.echo(f"Rolling a {sides}-sided dice {times} time(s)")
$ roll --rolls=42
Usage: roll [OPTIONS]
Try 'roll --help' for help.
Error: Invalid value for '--rolls': format must be 'NdM'
$ roll --rolls=2d12
Rolling a 12-sided dice 2 time(s)
$ roll
Rolls [1d6]: 42
Error: format must be 'NdM'
Rolls [1d6]: 2d12
Rolling a 12-sided dice 2 time(s)
可选值¶
向选项提供值可以是可选的,在这种情况下,仅提供选项的标志而不提供值将显示提示或使用其 flag_value
.
设置 is_flag=False, flag_value=value
告诉Click仍然可以向该选项传递一个值,但如果只为该标志指定 flag_value
使用。
@click.command()
@click.option("--name", is_flag=False, flag_value="Flag", default="Default")
def hello(name):
click.echo(f"Hello, {name}!")
$ hello
Hello, Default!
$ hello --name Value
Hello, Value!
$ hello --name
Hello, Flag!
如果选项 prompt
启用,然后设置 prompt_required=False
告诉Click仅在给出选项的标志时才显示提示,而不是在根本没有提供该选项的情况下显示提示。
@click.command()
@click.option('--name', prompt=True, prompt_required=False, default="Default")
def hello(name):
click.echo(f"Hello {name}!")
$ hello
Hello Default!
$ hello --name Value
Hello Value!
$ hello --name
Name [Default]:
如果 required=True
,则未给出选项仍会提示,但如果只给出标志也会提示。