当使用Python
click库编写命令行界面(CLI)时,是否可以定义三个选项,其中仅当第一个(可选)选项未设置时才需要第二个和第三个选项?
我的用例是一个登录系统,该系统允许我通过authentication token
(选项1)或通过username
(选项2)和password
(选项3)进行身份验证。
如果给出了令牌,则无需检查username
和password
定义令牌或提示它们。否则,如果忽略了此令牌,然后username
和password
成为必需的,必须给予。
可以使用回调以某种方式完成此操作吗?
我的入门代码当然不能反映预期的模式:
@click.command()
@click.option('--authentication-token', prompt=True, required=True)
@click.option('--username', prompt=True, required=True)
@click.option('--password', hide_input=True, prompt=True, required=True)
def login(authentication_token, username, password):
print(authentication_token, username, password)
if __name__ == '__main__':
login()
这可以通过构建从派生的自定义类来完成click.Option
,并在该类中使用如下click.Option.handle_parse_result()
方法:
import click
class NotRequiredIf(click.Option):
def __init__(self, *args, **kwargs):
self.not_required_if = kwargs.pop('not_required_if')
assert self.not_required_if, "'not_required_if' parameter required"
kwargs['help'] = (kwargs.get('help', '') +
' NOTE: This argument is mutually exclusive with %s' %
self.not_required_if
).strip()
super(NotRequiredIf, self).__init__(*args, **kwargs)
def handle_parse_result(self, ctx, opts, args):
we_are_present = self.name in opts
other_present = self.not_required_if in opts
if other_present:
if we_are_present:
raise click.UsageError(
"Illegal usage: `%s` is mutually exclusive with `%s`" % (
self.name, self.not_required_if))
else:
self.prompt = None
return super(NotRequiredIf, self).handle_parse_result(
ctx, opts, args)
要使用自定义类,请将cls
参数传递给click.option
decorator,如下所示:
@click.option('--username', prompt=True, cls=NotRequiredIf,
not_required_if='authentication_token')
之所以可行,是因为click是一个设计良好的OO框架。该@click.option()
装饰通常实例化一个click.Option
对象,但允许与被覆盖这种行为cls
参数。因此,click.Option
在我们自己的类中继承并超越所需的方法是相对容易的事情。
在这种情况下,我们在乘坐click.Option.handle_parse_result()
和禁用需要user/password
,如果authentication- token
令牌存在,并且抱怨,如果两者user/password
都authentication-token
存在。
@click.command()
@click.option('--authentication-token')
@click.option('--username', prompt=True, cls=NotRequiredIf,
not_required_if='authentication_token')
@click.option('--password', prompt=True, hide_input=True, cls=NotRequiredIf,
not_required_if='authentication_token')
def login(authentication_token, username, password):
click.echo('t:%s u:%s p:%s' % (
authentication_token, username, password))
if __name__ == '__main__':
login('--username name --password pword'.split())
login('--help'.split())
login(''.split())
login('--username name'.split())
login('--authentication-token token'.split())
来自login('--username name --password pword'.split())
:
t:None u:name p:pword
来自login('--help'.split())
:
Usage: test.py [OPTIONS]
Options:
--authentication-token TEXT
--username TEXT NOTE: This argument is mutually exclusive with
authentication_token
--password TEXT NOTE: This argument is mutually exclusive with
authentication_token
--help Show this message and exit.
Node.js 自带了各种命令行选项。 这些选项开放了内置的调试、执行脚本的多种方式、以及其他有用的运行时选项。运行 man node 可在一个终端中查看操作手册。 概要 node [options] [v8 options] [script.js | -e "script" | -] [--] [arguments] node debug [script.js | -e "script" | <
Shebang 行 几乎每个 Perl 程序都如此开始: #!/usr/bin/perl 这是 UNIX 结构,它告诉 Shell 直接执行余下的输入程序文件。 你可以在此行添加 Perl 的任何命令行选项,它们将成为选项之后命令行的一部分。 如果你有一个程序包含: #!/usr/bin/perl -T 然后执行: perl -l program.pl -l 和 -T 两个选项都会使用,但
进程优先权 当计划线程时使用的优先权。在有需要时可调整优先权到较高或较低。 文件位置 你可以为不同的文件类型改变文件夹。在默认情况下,大部分的文件设置在设置位置。然而, 一些文件是保存在 profiles目录和全部日志文件保存在 logs 目录。 文件关联(只限于完整版本) 文件关联是 Navicat 使用什么来打开 Navicat 已保存的文件。例如:.npt 文件(数据传输设置文件)将会使用数
我希望,如果我选择“mammals”,动物选择选项只显示值为1的选项data-animal_class。 我知道如何获得哺乳动物值,但我不知道如何使用过滤器 这是我的代码:
Ruby 一般是从命令行运行,方式如下: 解释器可以通过下列选项被调用,来控制解释器的环境和行为。 选项 描述 -a 与 -n 或 -p 一起使用时,可以打开自动拆分模式(auto split mode)。请查看 -n 和 -p 选项。 -c 只检查语法,不执行程序。 -C dir 在执行前改变目录(等价于 -X)。 -d 启用调试模式(等价于 -debug)。 -F pat 指定 pat 作为默
Envoy由JSON配置文件以及一组命令行选项驱动。以下是Envoy支持的命令行选项。 -c \, --config-path \ (必选)指向v1或v2 JSON/YAML/proto3配置文件)的路径。若设置-v2-config-only选项,则将被解析为一个v2引导配置文件,如果是v1 JSON配置文件,则返回失败。对于v2配置文件,有效的扩展名是.json,.yaml,.pb和.pb_te