选项
向命令添加选项可以通过 option()
装饰者。因为选项可以有不同的版本,所以有大量的参数来配置它们的行为。click 中的选项与 positional arguments .
为你的选择命名
命名规则可以在 参数名 . 简而言之,您可以参考该选项 隐含地 由最长的破折号前缀参数:
@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)
基本值选项
最基本的选项是值选项。这些选项接受一个值参数。如果未提供类型,则使用默认值的类型。如果没有提供默认值,则假定类型为 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('from %s to %s' % (from_, 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.
多值选项
有时,你可以选择多个论点。对于选项,只支持固定数量的参数。这可以通过 nargs
参数。这些值随后存储为一个元组。
@click.command() @click.option('--pos', nargs=2, type=float) def findme(pos): click.echo('%s / %s' % pos)
在命令行上:
$ findme --pos 2.0 3.0 2.0 / 3.0
元组作为多值选项
4.0 新版功能。
你可以通过使用 nargs 设置为特定的数字,结果元组中的每个项都属于同一类型。这可能不是你想要的。通常,您可能希望对元组中的不同索引使用不同的类型。为此,可以直接将元组指定为类型:
@click.command() @click.option('--item', type=(str, int)) def putitem(item): click.echo('name=%s id=%d' % item)
在命令行上:
$ 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): click.echo('name=%s id=%d' % item)
多种选择方案
类似于 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
计数
在一些非常罕见的情况下,使用选项的重复来向上计数整数是很有趣的。这可用于详细标志,例如:
@click.command() @click.option('-v', '--verbose', count=True) def log(verbose): click.echo('Verbosity: %s' % 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
如果您真的不想关闭开关,您只需定义一个开关并手动通知 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
请注意,如果选项中已经包含斜线(例如,如果使用 Windows 样式参数 /
是前缀字符),您也可以通过 ;
而是:
@click.command() @click.option('/debug;/no-debug') def log(debug): click.echo('debug=%s' % debug) if __name__ == '__main__': log()
在 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
类型。它可以用有效值列表进行实例化。
例子:
@click.command() @click.option('--hash-type', type=click.Choice(['md5', 'sha1'])) def digest(hash_type): click.echo(hash_type)
它是什么样子的:
$ digest --hash-type=md5 md5 $ digest --hash-type=foo Usage: digest [OPTIONS] Try "digest --help" for help. Error: Invalid value for "--hash-type": invalid choice: foo. (choose from md5, sha1) $ digest --help Usage: digest [OPTIONS] Options: --hash-type [md5|sha1] --help Show this message and exit.
注解
您应该只将选项作为列表或元组传递。其他 iTerables(如发电机)可能会产生令人惊讶的结果。
提示
在某些情况下,您需要可以从命令行提供的参数,但如果没有提供,则请求用户输入。这可以通过定义提示字符串通过 Click 来实现。
例子:
@click.command() @click.option('--name', prompt=True) def hello(name): click.echo('Hello %s!' % 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('Hello %s!' % name)
它是什么样子的:
$ hello Your name please: John Hello John!
密码提示
Click 还支持隐藏提示和请求确认。这对于输入密码很有用:
@click.command() @click.option('--password', prompt=True, hide_input=True, confirmation_prompt=True) def encrypt(password): click.echo('Encrypting password to %s' % password.encode('rot13'))
它是什么样子的:
$ encrypt Password: Repeat for confirmation:
因为这种参数组合非常常见,所以也可以用 password_option()
装饰者:
@click.command() @click.password_option() def encrypt(password): click.echo('Encrypting password to %s' % password.encode('rot13'))
提示的动态默认值
这个 auto_envvar_prefix
和 default_map
上下文选项允许程序从环境或配置文件中读取选项值。但是,这会覆盖提示机制,这样用户就不能选择以交互方式更改值。
如果要让用户配置默认值,但在命令行上未指定该选项时仍会提示用户,则可以通过提供一个 Callable 作为默认值来进行配置。例如,要从环境中获取默认值,请执行以下操作:
@click.command() @click.option('--username', prompt=True, default=lambda: os.environ.get('USER', '')) def hello(username): print("Hello,", username)
要描述默认值是什么,请在 show_default
.
@click.command() @click.option('--username', prompt=True, default=lambda: os.environ.get('USER', ''), show_default='current user') def hello(username): print("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
以及价值。上下文提供一些有用的特性,例如退出应用程序,并提供对其他已处理参数的访问。
这里是一个例子 --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
回调签名更改
在 Click 2.0 中,回调的签名已更改。有关这些更改的详细信息,请参阅 升级到 2.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 2.0 中,回调的签名已更改。有关这些更改的详细信息,请参阅 升级到 2.0 .
来自环境变量的值
click 的一个非常有用的特性是除了常规参数之外,还可以接受来自环境变量的参数。这使得工具的自动化更加容易。例如,您可能希望传递一个配置文件, --config
参数,也支持导出 TOOL_CONFIG=hello.cfg
关键价值对,以获得更好的发展经验。
Click 有两种方式支持这一点。一种方法是自动构建环境变量,而环境变量只支持选项。要启用此功能,请 auto_envvar_prefix
需要将参数传递给调用的脚本。然后将每个命令和参数添加为大写下划线分隔变量。如果有一个子命令调用 foo
接受一个被称为 bar
前缀是 MY_TOOL
,那么变量是 MY_TOOL_FOO_BAR
.
示例用法:
@click.command() @click.option('--username') def greet(username): click.echo('Hello %s!' % username) if __name__ == '__main__': greet(auto_envvar_prefix='GREETER')
从命令行:
$ export GREETER_USERNAME=john $ greet Hello john!
使用时 auto_envvar_prefix
对于命令组,命令名需要包含在环境变量中,在前缀和参数名之间, i.e. PREFIX_COMMAND_VARIABLE .
例子:
@click.group() @click.option('--debug/--no-debug') def cli(debug): click.echo('Debug mode is %s' % ('on' if debug else 'off')) @cli.command() @click.option('--username') def greet(username): click.echo('Hello %s!' % 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('Hello %s!' % 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('writable=%s' % 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('debug=%s' % debug) if __name__ == '__main__': log()
范围选项
一个特别提到应该去 IntRange
类型,其工作原理与 INT
类型,但将值限制在特定范围内(包括两边)。它有两种模式:
- 默认模式(非夹持模式),其中值超出范围将导致错误。
0-5
会回来5
为了价值10
或0
为了价值-1
(例如)。
例子:
@click.command() @click.option('--count', type=click.IntRange(0, 20, clamp=True)) @click.option('--digit', type=click.IntRange(0, 10)) def repeat(count, digit): click.echo(str(digit) * count) if __name__ == '__main__': repeat()
从命令行:
$ repeat --count=1000 --digit=5 55555555555555555555 $ repeat --count=1000 --digit=12 Usage: repeat [OPTIONS] Try "repeat --help" for help. Error: Invalid value for "--digit": 12 is not in the valid range of 0 to 10.
如果你通过 None
对于任何边,这意味着该边的范围是开放的。
用于验证的回调
在 2.0 版更改。
如果要应用自定义验证逻辑,可以在参数回调中执行此操作。这些回调既可以修改值,也可以在验证不起作用时引发错误。
在 Click 1.0 中,只能提升 UsageError
但从 click 2.0 开始,您还可以提高 BadParameter
错误,这有一个额外的优点,即它将自动格式化错误消息以同时包含参数名。
例子:
def validate_rolls(ctx, param, value): try: rolls, dice = map(int, value.split('d', 2)) return (dice, rolls) except ValueError: raise click.BadParameter('rolls need to be in format NdM') @click.command() @click.option('--rolls', callback=validate_rolls, default='1d6') def roll(rolls): click.echo('Rolling a %d-sided dice %d time(s)' % rolls) if __name__ == '__main__': roll()
看起来像是:
$ roll --rolls=42 Usage: roll [OPTIONS] Error: Invalid value for "--rolls": rolls need to be in format NdM $ roll --rolls=2d12 Rolling a 12-sided dice 2 time(s)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论