实用程序 — 单击文档

来自菜鸟教程
Click/docs/7.x/utils
跳转至:导航、​搜索

公用事业

除了 Click 提供的与参数解析和处理接口的功能外,它还提供了一堆对编写命令行实用程序很有用的插件功能。

打印到标准输出

最明显的帮助器是 echo() 函数,它在许多方面的工作方式类似于 Python 的 print 语句或函数。 主要区别在于它在 Python 2 和 3 中的工作方式相同,它可以智能地检测错误配置的输出流,并且永远不会失败(Python 3 除外;有关更多信息,请参阅 Python 3 限制 )。

例子:

import click

click.echo('Hello World!')

最重要的是,它可以打印 Unicode 和二进制数据,不像 Python 3 中内置的 print 函数不能输出任何字节。 然而,默认情况下它会发出一个尾随换行符,需要通过传递 nl=False 来抑制它:

click.echo(b'\xe2\x98\x83', nl=False)

最后但并非最不重要的 echo() 使用 click 的智能内部输出流到支持 Windows 控制台上的 unicode 输出的 stdout 和 stderr。 这意味着只要您使用 click.echo,您就可以输出 unicode 字符(关于可以显示哪些字符的默认字体有一些限制)。 此功能是 Click 6.0 中的新增功能。

6.0 版中的新功能。


Click now 模拟 Windows 上的输出流,以通过单独的 API 支持到 Windows 控制台的 unicode。 有关详细信息,请参阅 Windows 控制台说明

3.0 版中的新功能。


从 Click 3.0 开始,您还可以通过传递 err=True 轻松打印到标准错误:

click.echo('Hello World!', err=True)

ANSI 颜色

2.0 版中的新功能。


从 Click 2.0 开始,echo() 函数获得了处理 ANSI 颜色和样式的额外功能。 请注意,在 Windows 上,此功能仅在安装了 colorama 时才可用。 如果已安装,则会智能处理 ANSI 代码。 请注意,在 Python 2 中,echo 函数不会解析字节数组中的颜色代码信息。

这主要意味着:

  • 如果流未连接到终端,Click 的 echo() 函数将自动剥离 ANSI 颜色代码。
  • echo() 函数将透明地连接到 Windows 上的终端并将 ANSI 代码转换为终端 API 调用。 这意味着颜色在 Windows 上的工作方式与在其他操作系统上的工作方式相同。

colorama支持的注意事项:点击会自动检测colorama何时可用并使用它。 不要不要colorama.init()

要安装 colorama,请运行以下命令:

$ pip install colorama

要设置字符串样式,可以使用 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() 函数类似,但始终写入标准输出,如果可能,通过寻呼机。

例子:

如果你想对大量文本使用分页器,特别是如果预先生成所有内容需要很多时间,你可以传递一个生成器(或生成器函数)而不是一个字符串:


屏幕清除

2.0 版中的新功能。


要清除终端屏幕,您可以使用从 Click 2.0 开始提供的 clear() 函数。 它顾名思义:它以与平台无关的方式清除整个可见屏幕:

import click
click.clear()

从终端获取字符

2.0 版中的新功能。


通常,从终端读取输入时,您将从标准输入读取。 但是,这是缓冲输入,在该行终止之前不会显示。 在某些情况下,您可能不想这样做,而是在写入时读取单个字符。

为此,Click 提供了 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,它们分别被转换为键盘中断和文件结束异常。 这样做是因为否则,很容易忘记这一点并创建无法正确退出的脚本。


等待按键

2.0 版中的新功能。


有时,暂停直到用户按下键盘上的任意键很有用。 这在 Windows 上特别有用,默认情况下 cmd.exe 将在命令执行结束时关闭窗口,而不是等待。

在点击中,这可以通过 pause() 函数来完成。 此功能将向终端打印一条快速消息(可以自定义)并等待用户按下某个键。 除此之外,如果脚本不交互运行,它也会变成NOP(无操作指令)。

例子:

import click
click.pause()

启动编辑器

2.0 版中的新功能。


Click 支持通过 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')

启动应用程序

2.0 版中的新功能。


Click 支持通过 launch() 启动应用程序。 这可用于打开与 URL 或文件类型关联的默认应用程序。 例如,这可用于启动 Web 浏览器或图片查看器。 除此之外,它还可以启动文件管理器并自动选择提供的文件。

用法示例:

click.launch("https://click.palletsprojects.com/")
click.launch("/my/downloaded/file.txt", locate=True)

打印文件名

因为文件名可能不是 Unicode,所以格式化它们可能有点棘手。 通常,这在 Python 2 中比在 3 中更容易,因为您可以使用 print 函数将字节写入标准输出,但在 Python 3 中,您将始终需要以 Unicode 进行操作。

点击的方式是通过 format_filename() 函数。 它会尽力将文件名转换为 Unicode,并且永远不会失败。 这使得在完整 Unicode 字符串的上下文中使用这些文件名成为可能。

例子:

click.echo('Path: %s' % click.format_filename(b'foo.txt'))

标准流

对于命令行实用程序,可靠地访问输入和输出流非常重要。 Python 通常通过 sys.stdout 和朋友提供对这些流的访问,但不幸的是,2.x 和 3.x 之间存在 API 差异,尤其是这些流如何响应 Unicode 和二进制数据。

正因为如此,click 提供了 get_binary_stream()get_text_stream() 函数,它们在不同的 Python 版本和各种终端配置下产生一致的结果。

最终结果是这些函数将始终返回一个函数流对象(Python 3 中非常奇怪的情况除外;请参阅 Python 3 限制 )。

例子:

import click

stdin_text = click.get_text_stream('stdin')
stdout_binary = click.get_binary_stream('stdout')

6.0 版中的新功能。


Click now 模拟 Windows 上的输出流,以通过单独的 API 支持到 Windows 控制台的 unicode。 有关详细信息,请参阅 Windows 控制台说明


智能文件打开

3.0 版中的新功能。


从 Click 3.0 开始,从 File 类型打开文件的逻辑通过 open_file() 函数公开。 它可以智能地打开标准输入/标准输出以及任何其他文件。

例子:

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')

查找应用程序文件夹

2.0 版中的新功能。


很多时候,您想打开属于您的应用程序的配置文件。 但是,不同的操作系统根据其标准将这些配置文件存储在不同的位置。 Click 提供了一个 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['%s.%s' % (section, key)] = value
    return rv

显示进度条

2.0 版中的新功能。


有时,您有需要处理大量数据的命令行脚本,但您想快速向用户显示有关需要多长时间的一些进度。 Click 通过 progressbar() 函数支持简单的进度条渲染。

基本用法非常简单:想法是您有一个要对其进行操作的可迭代对象。 对于迭代中的每个项目,可能需要一些时间来进行处理。 所以说你有一个这样的循环:

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('sleep({})...'.format(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)

有时,可能需要迭代外部迭代器,并不规则地推进进度条。 为此,您需要指定长度(并且不可迭代),并在上下文返回值上使用 update 方法,而不是直接对其进行迭代:

with click.progressbar(length=total_size,
                       label='Unzipping archive') as bar:
    for archive in zip_file:
        archive.extract()
        bar.update(archive.size)