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和某些其他操作系统上,其编码处理是有问题的。

最大的挫折源是init系统、部署工具或cron作业调用的单击脚本将拒绝工作,除非导出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脚本之前,需要导出这些值。

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