Python3 utf8 编解码器未按 Docker ubuntu:trusty 中的预期解码
Python3 utf8 codecs not decoding as expected in Docker ubuntu:trusty
下面的事情真的让我很烦恼,我笔记本电脑上的 python 版本和 Docker 的 ubuntu:trusty 图像中的 python 版本打印出不同的结果使用他们的编解码器,这是什么原因?
例如,python3 在我的笔记本电脑上(ubuntu,可信赖):
Python 3.4.3 (default, Apr 14 2015, 14:16:55)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'’'
>>>
python3 Docker ubuntu:latest:
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'\u2019'
>>>
我可以在 Docker 的 ubuntu:trusty 上使用 python3 编解码器将 b'\xe2\x80\x99' 解码为 ''' 吗?[=15=]
这听起来像是语言环境配置问题。 Python 在这两个位置的行为可能不同,因为它 运行 所在的终端会话配置不同。
检查 Ubuntu Docker 机器上的 locale
设置,看看您在终端会话中使用的是 UTF-8 语言环境。特别是,查看您的 CTYPE
是否已切换到 C
。 (我以前在服务器上看到过,但不知道为什么会这样。)这可能会影响 Python 控制台是否将其视为可打印字符,从而决定是将其显示为本身还是显示为转义序列。这也会影响其他终端程序。
我能够通过摆弄语言环境设置在 Python 3.4.0 on OS X 中重现此行为。
[@ in ~]
$ locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
[@ in ~]
$ python3.4
Python 3.4.0 (v3.4.0:04f714765c13, Mar 15 2014, 23:02:41)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'’'
>>> quit()
[@ in ~]
$ LC_CTYPE=C python3.4
Python 3.4.0 (v3.4.0:04f714765c13, Mar 15 2014, 23:02:41)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'\u2019'
>>> quit()
如果这是您的语言环境设置,您需要在 Docker Ubuntu 实例上设置 rc 文件,以将您的语言环境配置为适合您的 UTF-8 语言环境,或者让您的区域设置通过 SSH 或您正在使用的任何连接方法传播,以便在那里配置您的远程终端会话。通过连接传播您的区域设置可能更有意义,因为它可以为您连接的其他服务器或帐户修复它。
下面说明了发生了什么以及如何解决它:
root@df329ec1fe88:/# python3
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'\u2019'
>>> exit()
root@df329ec1fe88:/# locale -a
C
C.UTF-8
POSIX
root@df329ec1fe88:/# locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
root@df329ec1fe88:/# sudo locale-gen "en_US.UTF-8"
Generating locales...
en_US.UTF-8... done
Generation complete.
root@df329ec1fe88:/# sudo dpkg-reconfigure locales
Generating locales...
en_US.UTF-8... up-to-date
Generation complete.
root@df329ec1fe88:/# echo "export LC_ALL=en_US.utf8" >> ~/.bashrc
root@df329ec1fe88:/# echo "export LANG=en_US.utf8" >> ~/.bashrc
root@df329ec1fe88:/# echo "export LANGUAGE=en_US.utf8" >> ~/.bashrc
root@df329ec1fe88:/# source ~/.bashrc
root@df329ec1fe88:/# locale
LANG=en_US.utf8
LANGUAGE=en_US.utf8
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=en_US.utf8
root@df329ec1fe88:/# python3
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'’'
>>> exit()
root@df329ec1fe88:/#
然后您可以将此容器作为新映像提交以供将来使用,或者您可以在 Dockerfile 中自动执行此过程。基本上添加以下行:
RUN locale-gen "en_US.UTF-8"
RUN dpkg-reconfigure locales
RUN echo "export LC_ALL=en_US.utf8" >> ~/.bashrc
RUN echo "export LANG=en_US.utf8" >> ~/.bashrc
RUN echo "export LANGUAGE=en_US.utf8" >> ~/.bashrc
下面的事情真的让我很烦恼,我笔记本电脑上的 python 版本和 Docker 的 ubuntu:trusty 图像中的 python 版本打印出不同的结果使用他们的编解码器,这是什么原因? 例如,python3 在我的笔记本电脑上(ubuntu,可信赖):
Python 3.4.3 (default, Apr 14 2015, 14:16:55)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'’'
>>>
python3 Docker ubuntu:latest:
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'\u2019'
>>>
我可以在 Docker 的 ubuntu:trusty 上使用 python3 编解码器将 b'\xe2\x80\x99' 解码为 ''' 吗?[=15=]
这听起来像是语言环境配置问题。 Python 在这两个位置的行为可能不同,因为它 运行 所在的终端会话配置不同。
检查 Ubuntu Docker 机器上的 locale
设置,看看您在终端会话中使用的是 UTF-8 语言环境。特别是,查看您的 CTYPE
是否已切换到 C
。 (我以前在服务器上看到过,但不知道为什么会这样。)这可能会影响 Python 控制台是否将其视为可打印字符,从而决定是将其显示为本身还是显示为转义序列。这也会影响其他终端程序。
我能够通过摆弄语言环境设置在 Python 3.4.0 on OS X 中重现此行为。
[@ in ~]
$ locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
[@ in ~]
$ python3.4
Python 3.4.0 (v3.4.0:04f714765c13, Mar 15 2014, 23:02:41)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'’'
>>> quit()
[@ in ~]
$ LC_CTYPE=C python3.4
Python 3.4.0 (v3.4.0:04f714765c13, Mar 15 2014, 23:02:41)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'\u2019'
>>> quit()
如果这是您的语言环境设置,您需要在 Docker Ubuntu 实例上设置 rc 文件,以将您的语言环境配置为适合您的 UTF-8 语言环境,或者让您的区域设置通过 SSH 或您正在使用的任何连接方法传播,以便在那里配置您的远程终端会话。通过连接传播您的区域设置可能更有意义,因为它可以为您连接的其他服务器或帐户修复它。
下面说明了发生了什么以及如何解决它:
root@df329ec1fe88:/# python3
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'\u2019'
>>> exit()
root@df329ec1fe88:/# locale -a
C
C.UTF-8
POSIX
root@df329ec1fe88:/# locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
root@df329ec1fe88:/# sudo locale-gen "en_US.UTF-8"
Generating locales...
en_US.UTF-8... done
Generation complete.
root@df329ec1fe88:/# sudo dpkg-reconfigure locales
Generating locales...
en_US.UTF-8... up-to-date
Generation complete.
root@df329ec1fe88:/# echo "export LC_ALL=en_US.utf8" >> ~/.bashrc
root@df329ec1fe88:/# echo "export LANG=en_US.utf8" >> ~/.bashrc
root@df329ec1fe88:/# echo "export LANGUAGE=en_US.utf8" >> ~/.bashrc
root@df329ec1fe88:/# source ~/.bashrc
root@df329ec1fe88:/# locale
LANG=en_US.utf8
LANGUAGE=en_US.utf8
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=en_US.utf8
root@df329ec1fe88:/# python3
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.decode(b'\xe2\x80\x99','utf8')
'’'
>>> exit()
root@df329ec1fe88:/#
然后您可以将此容器作为新映像提交以供将来使用,或者您可以在 Dockerfile 中自动执行此过程。基本上添加以下行:
RUN locale-gen "en_US.UTF-8"
RUN dpkg-reconfigure locales
RUN echo "export LC_ALL=en_US.utf8" >> ~/.bashrc
RUN echo "export LANG=en_US.utf8" >> ~/.bashrc
RUN echo "export LANGUAGE=en_US.utf8" >> ~/.bashrc