参数
参数的作用类似于 options 但是是位置性的。由于选项的语法性质,它们也只支持选项特性的一个子集。Click 也不会尝试为您记录参数,并希望您手动记录这些参数,以避免出现难看的帮助页。
基本论点
最基本的选项是一个值的简单字符串参数。如果没有提供类型,则使用默认值的类型;如果没有提供默认值,则假定类型为 STRING
.
例子:
@click.command() @click.argument('filename') def touch(filename): click.echo(filename)
看起来像是:
$ touch foo.txt foo.txt
可变参数
第二个最常见的版本是可变参数,其中接受特定(或无限)数量的参数。这可以用 nargs
参数。如果设置为 -1
,则接受无限数量的参数。
然后将值作为元组传递。请注意,只能将一个参数设置为 nargs=-1
因为它会吞噬所有的参数。
例子:
@click.command() @click.argument('src', nargs=-1) @click.argument('dst', nargs=1) def copy(src, dst): for fn in src: click.echo('move %s to folder %s' % (fn, dst))
看起来像是:
$ copy foo.txt bar.txt my_folder move foo.txt to folder my_folder move bar.txt to folder my_folder
请注意,这不是您编写此应用程序的方式。原因是在这个特定的例子中,参数被定义为字符串。然而,文件名不是字符串!它们可能在某些操作系统上,但不一定在所有操作系统上。要获得更好的编写方法,请参阅下一节。
关于非空变量参数的说明
如果你来自 argparse
,您可能缺少对设置的支持 nargs
到 +
以指示至少需要一个参数。
这是由设置支持的 required=True
. 但是,如果您可以避免使用它,则不应该使用它,因为我们认为,如果变量参数为空,脚本应该优雅地降级为 noops。这样做的原因是,经常使用命令行中的通配符输入调用脚本,如果通配符为空,则它们不应出错。
文件参数
由于所有示例都已经使用了文件名,因此解释如何正确处理文件是很有意义的。如果命令行工具以 unix 的方式处理文件(也就是接受),那么它们会更有趣。 -
作为引用 stdin/stdout 的特殊文件。
Click 通过 click.File
智能处理文件的类型。它还正确地处理所有版本的 python 的 unicode 和字节,因此脚本保持非常可移植性。
例子:
@click.command() @click.argument('input', type=click.File('rb')) @click.argument('output', type=click.File('wb')) def inout(input, output): while True: chunk = input.read(1024) if not chunk: break output.write(chunk)
它的作用是:
$ inout - hello.txt hello ^D $ inout hello.txt - hello
文件路径参数
在上一个示例中,文件被立即打开。但是如果我们只需要文件名呢?na_ve 方法是使用默认的字符串参数类型。但是,请记住,click 是基于 Unicode 的,因此字符串始终是 Unicode 值。不幸的是,文件名可以是 Unicode 或字节,具体取决于使用的操作系统。因此,类型不足。
相反,您应该使用 Path
类型,它将自动处理此模糊性。它不仅返回字节或 Unicode,这取决于什么更有意义,而且还可以为您执行一些基本检查,例如存在性检查。
例子:
@click.command() @click.argument('f', type=click.Path(exists=True)) def touch(f): click.echo(click.format_filename(f))
它的作用是:
$ touch hello.txt hello.txt $ touch missing.txt Usage: touch [OPTIONS] F Try "touch --help" for help. Error: Invalid value for "F": Path "missing.txt" does not exist.
文件打开安全
这个 FileType
类型有一个问题需要处理,那就是决定何时打开文件。默认行为是“智能”的。这意味着它将打开 stdin/stdout 并立即打开要读取的文件。当文件无法打开时,这将给用户直接反馈,但它只会在首次执行 IO 操作时打开要写入的文件,方法是将文件自动包装在一个特殊的包装器中。
这种行为可以通过传球来强制 lazy=True
或 lazy=False
给建设者。如果文件以延迟方式打开,它将通过引发 FileError
.
由于打开用于写入的文件通常会立即清空该文件,因此只有在开发人员完全确定这是预期行为时,才应禁用惰性模式。
强制惰性模式对于避免资源处理混乱也非常有用。如果文件以惰性模式打开,它将收到 close_intelligently
方法来帮助确定文件是否需要关闭。这对于参数不需要,但对于使用 prompt()
函数,因为您不知道像 stdout 这样的流是打开的(以前已经打开过)还是需要关闭的真正文件。
从 click 2.0 开始,还可以通过传递以原子模式打开文件 atomic=True
. 在原子模式下,所有的写操作都将进入同一文件夹中的一个单独的文件中,完成后,文件将移到原始位置。如果修改了其他用户定期读取的文件,则此功能非常有用。
环境变量
和选项一样,参数也可以从环境变量中获取值。但是,与选项不同,它只支持显式命名的环境变量。
示例用法:
@click.command() @click.argument('src', envvar='SRC', type=click.File('r')) def echo(src): click.echo(src.read())
从命令行:
$ export SRC=hello.txt $ echo Hello World!
在这种情况下,它也可以是选择第一个环境变量的不同环境变量的列表。
一般来说,不建议使用此功能,因为它会导致用户产生很多混淆。
类选项参数
有时,您希望处理看起来像选项的参数。例如,假设您有一个名为 -foo.txt
. 如果以这种方式将其作为参数传递,则 Click 会将其视为选项。
要解决这个问题,请 Click“执行任何 POSIX 样式的命令行脚本所执行的操作”,即接受字符串 --
作为选项和参数的分隔符。后 --
标记,接受所有其他参数作为参数。
示例用法:
@click.command() @click.argument('files', nargs=-1, type=click.Path()) def touch(files): for filename in files: click.echo(filename)
从命令行:
$ touch -- -foo.txt bar.txt -foo.txt bar.txt
如果你不喜欢 --
marker,您可以将 ignore_unknown_options 设置为 true 以避免检查未知选项:
@click.command(context_settings={"ignore_unknown_options": True}) @click.argument('files', nargs=-1, type=click.Path()) def touch(files): for filename in files: click.echo(filename)
从命令行:
$ touch -foo.txt bar.txt -foo.txt bar.txt
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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