与Python 3.4,Unicode,不同语言和Windows有什么关系?

时间:2015-05-29 22:14:18

标签: python unicode

快乐的例子:

<ul>
  <li>
    <h2>Test 1</h2>
    <p>Lorem ipsum dolor sit amet.</p>
    <img src="http://lorempixel.com/120/150" />
    <button>Go now!</button>
  </li>
  <li>
    <h2>Test 2</h2>
    <p>Lorem ipsum dolor sit amet.</p>
    <img src="http://lorempixel.com/90/160" />
    <button>Go now!</button>
  </li>
  <li>
    <h2>Test 3</h2>
    <p>Lorem ipsum dolor sit amet.<br /> Lorem ipsum dolor sit amet.</p>
    <img src="http://lorempixel.com/100/260" />
    <button>Go now!</button>
  </li>
  <li>
    <h2>Test 4</h2>
    <p>Lorem ipsum dolor sit amet.</p>
    <button>Go now!</button>
  </li>
</ul>

不愉快的输出:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

czech = u'Leoš Janáček'.encode("utf-8")
print(czech)

pl = u'Zdzisław Beksiński'.encode("utf-8")
print(pl)

jp = u'リング 山村 貞子'.encode("utf-8")
print(jp)

chinese = u'五行'.encode("utf-8")
print(chinese)

MIR = u'Машина для Инженерных Расчётов'.encode("utf-8")
print(MIR)

pt = u'Minha Língua Portuguesa: çáà'.encode("utf-8")
print(pt)

如果我像这样打印它们:

b'Leo\xc5\xa1 Jan\xc3\xa1\xc4\x8dek'
b'Zdzis\xc5\x82aw Beksi\xc5\x84ski'
b'\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xb0 \xe5\xb1\xb1\xe6\x9d\x91 \xe8\xb2\x9e\xe5\xad\x90'
b'\xe4\xba\x94\xe8\xa1\x8c'
b'\xd0\x9c\xd0\xb0\xd1\x88\xd0\xb8\xd0\xbd\xd0\xb0 \xd0\xb4\xd0\xbb\xd1\x8f \xd0\x98\xd0\xbd\xd0\xb6\xd0\xb5\xd0\xbd\xd0\xb5\xd1\x80\xd0\xbd\xd1\x8b\xd1\x85 \xd0\xa0\xd0\xb0\xd1\x81\xd1\x87\xd1\x91\xd1\x82\xd0\xbe\xd0\xb2'
b'Minha L\xc3\xadngua Portuguesa: \xc3\xa7\xc3\xa1\xc3\xa0'

我明白了:

jp = u'リング 山村 貞子'
print(jp)

我还尝试了this question中的以下内容(以及涉及Traceback (most recent call last): File "x.py", line 5, in <module> print(jp) File "C:\Python34\lib\encodings\cp850.py", line 19, in encode return codecs.charmap_encode(input,self.errors,encoding_map)[0] UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-2: character maps to <undefined> 的其他替代方案):

sys.stdout.encoding

事情变得更加神秘:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
import sys

def safeprint(s):
    try:
        print(s)
    except UnicodeEncodeError:
        if sys.version_info >= (3,):
            print(s.encode('utf8').decode(sys.stdout.encoding))
        else:
            print(s.encode('utf8'))

jp = u'リング 山村 貞子'
safeprint(jp)

And the docs were not very helpful

那么,Python 3.4,Unicode,不同语言和Windows的处理是什么?几乎所有可能的例子我都能找到,处理Python 2.x。

是否有一种通用的跨平台方式在Python 3.4中以一种体面和非讨厌的方式从任何语言打印任何Unicode字符?

编辑:

我尝试在终端打字:

リング 山村 貞子

要更改代码页as proposed here并在注释中,它不起作用(包括使用sys.stdout.encoding的尝试)

2 个答案:

答案 0 :(得分:18)

更新: Since Python 3.6, the code example that prints Unicode strings directly should just work now (even without py -mrun)

Python可以在Windows控制台中以多种语言打印文本chcp所说的内容:

T:\> py -mpip install win-unicode-console
T:\> py -mrun your_script.py

其中your_script.py直接打印Unicode,例如:

#!/usr/bin/env python3
print('š áč')      # cz
print('ł ń')       # pl
print('リング')     # jp
print('五行')      # cn
print('ш я жх ё') # ru
print('í çáà')    # pt

您只需在Windows控制台中配置可显示所需字符的字体。

您还可以通过IDLE运行Python脚本,而无需安装非stdlib模块:

T:\> py -midlelib -r your_script.py

要写入文件/管道,请使用PYTHONIOENCODING=utf-8作为@Mark Tolonen suggested

T:\> set PYTHONIOENCODING=utf-8
T:\> py your_script.py >output-utf8.txt 

只有最后一个解决方案支持非BMP字符,例如 (U+1F612 UNAMUSED FACE) - py -mrun可以编写它们,但Windows控制台会将它们显示为框,即使字体支持相应的Unicode字符(尽管您可以复制 - 将这些框粘贴到另一个程序中,以获取字符。)

答案 1 :(得分:12)

问题 (请参阅下面的Python 3.6更新),Windows控制台支持适用于您的Windows版本所针对的区域的ANSI字符集。默认情况下,当输出不支持的字符时,Python会抛出异常。

Python可以读取environment variable以在其他编码中输出,或者更改错误处理默认值。下面,我已阅读控制台默认值并更改默认错误处理以打印?,而不是为控制台当前代码页中不支持的字符引发错误。

C:\>chcp
Active code page: 437   # Note, US Windows OEM code page.

C:\>set PYTHONIOENCODING=437:replace

C:\>example.py
Leo? Janá?ek
Zdzis?aw Beksi?ski
??? ?? ??
??
?????? ??? ?????????? ????????
Minha Língua Portuguesa: çáà

请注意,美国OEM代码页仅限于ASCII和一些西欧字符。

下面我指示Python使用UTF8,但由于Windows控制台不支持它,我将输出重定向到文件并在记事本中显示:

C:\>set PYTHONIOENCODING=utf8
C:\>example >out.txt
C:\>notepad out.txt

enter image description here

在Windows上,最好在使用多种语言时使用支持UTF-8而不是控制台的Python IDE。如果只使用一种语言,请在Region and Language控制面板中选择它作为系统区域设置,控制台将支持该语言的字符。

Python 3.6的更新

Python 3.6现在使用Windows Unicode API直接写入控制台,因此唯一的限制是控制台字体对字符的支持。以下代码适用于美国Windows控制台。我安装了中文语言包,如果更改了控制台字体,它甚至会显示中文和日文。即使没有正确的字体,控制台中也会显示替换字符。剪切粘贴到此网页等环境将正确显示字符。

#!python3.6
#coding: utf8
czech = 'Leoš Janáček'
print(czech)

pl = 'Zdzisław Beksiński'
print(pl)

jp = 'リング 山村 貞子'
print(jp)

chinese = '五行'
print(chinese)

MIR = 'Машина для Инженерных Расчётов'
print(MIR)

pt = 'Minha Língua Portuguesa: çáà'
print(pt)

输出:

Leoš Janáček
Zdzisław Beksiński
リング 山村 貞子
五行
Машина для Инженерных Расчётов
Minha Língua Portuguesa: çáà