Unicode 支持 — 单击文档

来自菜鸟教程
Click/docs/8.0.x/unicode-support
跳转至:导航、​搜索

Unicode 支持

Click 必须格外小心,以支持不同环境中的 Unicode 文本。

  • Unix 中的命令行传统上是字节,而不是 Unicode。 虽然有编码提示,但在某些情况下可能会中断。 最常见的一种是与具有不同语言环境的机器的 SSH 连接。

    由于缺乏对往返代理转义的支持,错误配置的环境可能会导致各种 Unicode 问题。 这不会在 Click 本身中修复!

  • 默认情况下,标准输入和输出以文本模式打开。 在某些情况下,单击必须以二进制模式重新打开流。 因为没有标准的方法来做到这一点,所以它可能并不总是有效。 在测试命令行应用程序时,这主要会成为一个问题。

    这不受支持:

    sys.stdin = io.StringIO('Input here')
    sys.stdout = io.StringIO()

    相反,您需要这样做:

    input = 'Input here'
    in_stream = io.BytesIO(input.encode('utf-8'))
    sys.stdin = io.TextIOWrapper(in_stream, encoding='utf-8')
    out_stream = io.BytesIO()
    sys.stdout = io.TextIOWrapper(out_stream, encoding='utf-8')

    请记住,在这种情况下,如果要访问缓冲区内容,则需要使用 out_stream.getvalue() 而不是 sys.stdout.getvalue(),因为包装器不会转发该方法。

  • sys.stdinsys.stdoutsys.stderr 默认是基于文本的。 当 Click 需要一个二进制流时,它会尝试发现底层的二进制流。

  • sys.argv 始终是文本。 这意味着 Click 中类型的输入值的本机类型是 Unicode,而不是字节。

    如果终端设置不正确并且 Python 无法确定编码,这会导致问题。 在这种情况下,Unicode 字符串将包含编码为代理转义的错误字节。

  • 在处理文件时,Click 将始终通过使用操作系统报告或猜测的文件系统编码来使用 Unicode 文件系统 API。 文件名支持代理,因此即使环境配置错误,也应该可以通过 File 类型打开文件。

代理处理

Click 执行标准库中的所有 Unicode 处理并受其行为的约束。 Unicode 需要格外小心。 这样做的原因是编码检测是在解释器中完成的,而在 Linux 和某些其他操作系统上,其编码处理是有问题的。

最大的挫折来源是初始化系统、部署工具或 cron 作业调用的 Click 脚本将拒绝工作,除非导出 Unicode 语言环境。

如果 Click 遇到这样的环境,它将阻止进一步执行以强制您设置语言环境。 这样做是因为 Click 一旦被调用就无法知道系统的状态并在 Python 的 Unicode 处理开始之前恢复这些值。

如果你看到类似这样的错误:

Traceback (most recent call last):
  ...
RuntimeError: Click will abort further execution because Python was
  configured to use ASCII as encoding for the environment. Consult
  https://click.palletsprojects.com/unicode-support/ for mitigation
  steps.

您正在处理 Python 认为您仅限于 ASCII 数据的环境。 这些问题的解决方案取决于您的计算机运行的区域设置。

例如,如果您有一台德国 Linux 机器,您可以通过将语言环境导出到 de_DE.utf-8 来解决问题:

export LC_ALL=de_DE.utf-8
export LANG=de_DE.utf-8

如果您使用的是美国机器,则 en_US.utf-8 是首选编码。 在一些较新的 Linux 系统上,您还可以尝试将 C.UTF-8 作为语言环境:

export LC_ALL=C.UTF-8
export LANG=C.UTF-8

据报道,在某些系统上,UTF-8 必须写为 UTF8,反之亦然。 要查看支持哪些语言环境,您可以调用 locale -a

您需要在调用 Python 脚本之前导出这些值。

在 Python 3.7 及更高版本中,由于 PEP 538PEP 540,在许多情况下您将不再获得 RuntimeError ],它改变了未配置环境中的默认假设。 这不会改变您的语言环境可能配置错误的一般问题。