公用事业¶
除了click提供的与参数解析和处理接口的功能外,它还提供了一系列插件功能,这些功能对于编写命令行实用程序很有用。
打印到stdout¶
最明显的助手是 echo()
函数,在许多方面与Python类似 print
语句或函数。主要的区别在于,它在许多不同的终端环境中都是一样的。
例子::
import click
click.echo('Hello World!')
它可以输出文本和二进制数据。默认情况下,它将发出一个尾随的换行符,这需要通过传递来抑制 nl=False
::
click.echo(b'\xe2\x98\x83', nl=False)
最后但并非最不重要 echo()
使用click的智能内部输出流到stdout和stderr,后者在Windows控制台上支持Unicode输出。这意味着只要你使用 click.echo 有一些字符可以显示在unicode字符上。
Changelog
在 6.0 版本加入.
单击“在Windows上模拟输出流”,通过单独的API支持unicode到Windows控制台。有关详细信息,请参阅 Windows控制台说明 .
Changelog
在 3.0 版本加入.
您还可以通过 err=True
::
click.echo('Hello World!', err=True)
ANSI颜色¶
Changelog
在 2.0 版本加入.
这个 echo()
函数支持ANSI颜色和样式。在Windows上,它使用 colorama 。
这主要意味着:
点击的
echo()
如果流未连接到终端,函数将自动删除ANSI颜色代码。这个
echo()
函数将透明地连接到Windows上的终端,并将ANSI代码转换为终端API调用。这意味着颜色在Windows上的作用与在其他操作系统上的作用相同。
在Windows上,Click使用Colorama而不调用 colorama.init()
。您仍然可以在代码中调用它,但Click不需要它。
为了设计一根绳子的样式, style()
函数可用于:
import click
click.echo(click.style('Hello World!', fg='green'))
click.echo(click.style('Some more text', bg='blue', fg='white'))
click.echo(click.style('ATTENTION', blink=True, bold=True))
结合 echo()
和 style()
也可以在一个函数中调用 secho()
::
click.secho('Hello World!', fg='green')
click.secho('Some more text', bg='blue', fg='white')
click.secho('ATTENTION', blink=True, bold=True)
寻呼机支持¶
在某些情况下,您可能希望在终端上显示长文本,并让用户在其中滚动。这可以通过使用 echo_via_pager()
类似于 echo()
函数,但始终通过寻呼机写入stdout和(如果可能)。
例子:
@click.command()
def less():
click.echo_via_pager("\n".join(f"Line {idx}" for idx in range(200)))
如果要对大量文本使用寻呼机,特别是如果提前生成所有内容需要花费大量时间,则可以传递生成器(或生成器函数)而不是字符串:
def _generate_output():
for idx in range(50000):
yield f"Line {idx}\n"
@click.command()
def less():
click.echo_via_pager(_generate_output())
屏幕清除¶
Changelog
在 2.0 版本加入.
要清除终端屏幕,可以使用 clear()
从单击2.0开始提供的函数。它按照名字的意思做:它以一种平台不可知论的方式清除整个可见屏幕:
import click
click.clear()
从终端获取字符¶
Changelog
在 2.0 版本加入.
通常,当从终端读取输入时,您将从标准输入读取。但是,这是缓冲输入,在线路终止之前不会显示。在某些情况下,您可能不想这样做,而是在编写单个字符时读取它们。
为此,单击提供 getchar()
从终端缓冲区中读取单个字符并将其作为Unicode字符返回的函数。
请注意,即使stdin是管道,此函数也始终从终端读取。
例子::
import click
click.echo('Continue? [yn] ', nl=False)
c = click.getchar()
click.echo()
if c == 'y':
click.echo('We will go on')
elif c == 'n':
click.echo('Abort!')
else:
click.echo('Invalid input :(')
请注意,这将读取原始输入,这意味着箭头键之类的东西将以平台的本机转义格式显示。翻译的字符只有 ^C
和 ^D
分别转换为键盘中断和文件结束异常。这样做是因为否则,很容易忘记这一点并创建无法正确退出的脚本。
等待按键¶
Changelog
在 2.0 版本加入.
有时,暂停直到用户按下键盘上的任何键是有用的。这在Windows上特别有用 cmd.exe
默认情况下,将在命令执行结束时关闭窗口,而不是等待。
在click中,可以通过 pause()
功能。此功能将向终端打印一条快速消息(可自定义),等待用户按键。除此之外,如果脚本不以交互方式运行,它也将成为NOP(无操作指令)。
例子::
import click
click.pause()
启动编辑器¶
Changelog
在 2.0 版本加入.
单击支持自动启动编辑器 edit()
. 这对于询问用户多行输入非常有用。它将自动打开用户定义的编辑器或返回到合理的默认值。如果用户关闭编辑器而不保存,返回值将为 None
,否则输入文本。
示例用法:
import click
def get_commit_message():
MARKER = '# Everything below is ignored\n'
message = click.edit('\n\n' + MARKER)
if message is not None:
return message.split(MARKER, 1)[0].rstrip('\n')
或者,该函数还可以用于为特定文件名的文件启动编辑器。在这种情况下,返回值总是 None .
示例用法:
import click
click.edit(filename='/etc/passwd')
启动应用程序¶
Changelog
在 2.0 版本加入.
单击支持通过 launch()
. 这可用于打开与URL或文件类型关联的默认应用程序。例如,它可以用于启动Web浏览器或图片查看器。除此之外,它还可以启动文件管理器并自动选择提供的文件。
示例用法:
click.launch("https://click.palletsprojects.com/")
click.launch("/my/downloaded/file.txt", locate=True)
打印文件名¶
因为文件名可能不是Unicode,格式化它们可能有点棘手。
使用Click的方式是通过 format_filename()
功能。它尽最大努力将文件名转换为Unicode,并且永远不会失败。这使得在完整的Unicode字符串上下文中使用这些文件名成为可能。
例子::
click.echo(f"Path: {click.format_filename(b'foo.txt')}")
标准流¶
对于命令行实用程序,可靠地访问输入和输出流非常重要。python通常通过 sys.stdout
和friends,但不幸的是,2.x和3.x之间存在API差异,特别是在这些流如何响应Unicode和二进制数据方面。
因此,单击提供 get_binary_stream()
和 get_text_stream()
函数,它在不同的Python版本和各种终端配置中产生一致的结果。
最终的结果是,这些函数将始终返回一个函数流对象(除非在非常奇怪的情况下;请参见 Unicode支持 )
例子::
import click
stdin_text = click.get_text_stream('stdin')
stdout_binary = click.get_binary_stream('stdout')
Changelog
在 6.0 版本加入.
现在单击模拟Windows上的输出流,以通过单独的API支持Unicode到Windows控制台。有关详细信息,请参阅 Windows控制台说明 .
智能文件打开¶
Changelog
在 3.0 版本加入.
从click 3.0开始,从 File
类型通过 open_file()
功能。它可以智能地打开stdin/stdout以及任何其他文件。
例子::
import click
stdout = click.open_file('-', 'w')
test_file = click.open_file('test.txt', 'w')
如果返回stdin或stdout,返回值将包装在特殊文件中,上下文管理器将阻止关闭该文件。这使得对标准流的处理透明化,并且您始终可以这样使用它::
with click.open_file(filename, 'w') as f:
f.write('Hello World!\n')
正在查找应用程序文件夹¶
Changelog
在 2.0 版本加入.
通常,您希望打开属于应用程序的配置文件。但是,不同的操作系统根据其标准将这些配置文件存储在不同的位置。单击提供 get_app_dir()
函数,根据操作系统为应用程序的每个用户配置文件返回最合适的位置。
示例用法:
import os
import click
import ConfigParser
APP_NAME = 'My Application'
def read_config():
cfg = os.path.join(click.get_app_dir(APP_NAME), 'config.ini')
parser = ConfigParser.RawConfigParser()
parser.read([cfg])
rv = {}
for section in parser.sections():
for key, value in parser.items(section):
rv[f"{section}.{key}"] = value
return rv
显示进度条¶
有时,您有需要处理大量数据的命令行脚本,但您希望快速向用户显示有关所需时间的一些进度。点击支持简单的进度条渲染 progressbar()
功能。
备注
如果您发现您的要求超出了Click进度条所支持的范围,请尝试使用 tqdm 。
基本用法非常简单:其思想是您有一个要操作的iterable。对于iterable中的每个项,可能需要一些时间来进行处理。假设你有一个这样的循环:
for user in all_the_users_to_process:
modify_the_user(user)
要将其与自动更新进度条连接起来,您只需将代码更改为:
import click
with click.progressbar(all_the_users_to_process) as bar:
for user in bar:
modify_the_user(user)
单击将自动在终端上打印进度条,并计算剩余时间。计算剩余时间需要iterable有一个长度。如果它没有长度,但您知道长度,则可以显式提供:
with click.progressbar(all_the_users_to_process,
length=number_of_users) as bar:
for user in bar:
modify_the_user(user)
注意 progressbar()
更新栏 之后 循环的每次迭代。所以这样的代码将正确呈现:
import time
with click.progressbar([1, 2, 3]) as bar:
for x in bar:
print(f"sleep({x})...")
time.sleep(x)
另一个有用的功能是将标签与进度条关联,进度条前面将显示:
with click.progressbar(all_the_users_to_process,
label='Modifying user accounts',
length=number_of_users) as bar:
for user in bar:
modify_the_user(user)
有时,可能需要迭代外部迭代器,并且不规则地推进进度条。为此,您需要指定长度(并且不可ITerable),并对上下文返回值使用update方法,而不是直接在其上迭代:
with click.progressbar(length=total_size,
label='Unzipping archive') as bar:
for archive in zip_file:
archive.extract()
bar.update(archive.size)