问题:为什么要在python中通过字符串声明unicode?
我仍在学习python,我对此表示怀疑:
在python 2.6.x中,我通常像这样在文件头中声明编码(如在PEP 0263中)
# -*- coding: utf-8 -*-
之后,我的字符串照常编写:
a = "A normal string without declared Unicode"
但是每次我看到python项目代码时,都不会在标头中声明编码。而是在每个这样的字符串处声明它:
a = u"A string with declared Unicode"
有什么不同?目的是什么?我知道Python 2.6.x默认设置了ASCII编码,但是它可以被标头声明覆盖,那么每个字符串声明的意义是什么?
附录:似乎我将文件编码和字符串编码混为一谈了。感谢您的解释:)
回答 0
正如其他人所提到的,这是两件事。
指定时# -*- coding: utf-8 -*-
,就是告诉Python保存的源文件是utf-8
。Python 2的默认值为ASCII(Python 3的默认值为utf-8
)。这只会影响解释器读取文件中字符的方式。
通常,无论编码是什么,将高unicode字符嵌入文件中可能都不是最好的主意。您可以使用字符串unicode转义,这两种编码都可以使用。
当您在字符串的u
前面声明一个字符串(如)时u'This is a string'
,它会告诉Python编译器该字符串是Unicode而不是字节。这大部分由解释器透明地处理。最明显的区别是您现在可以在字符串中嵌入unicode字符(即u'\u2665'
现在合法)。您可以使用from __future__ import unicode_literals
使其成为默认值。
这仅适用于Python 2;在Python 3中,默认值为Unicode,您需要b
在前面指定a (例如b'These are bytes'
,以声明字节序列)。
回答 1
就像其他人所说的,# coding:
指定保存源文件的编码。这是一些示例来说明这一点:
作为cp437(我的控制台编码)保存在磁盘上的文件,但未声明编码
b = 'über'
u = u'über'
print b,repr(b)
print u,repr(u)
输出:
File "C:\ex.py", line 1
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details
带有以下内容的文件输出# coding: cp437
:
über '\x81ber'
über u'\xfcber'
刚开始,Python不知道编码,并抱怨非ASCII字符。一旦知道了编码,字节字符串就会获取磁盘上实际存在的字节。对于Unicode字符串,Python读取\ x81,知道在cp437中是ü,并将其解码为ü的Unicode代码点,即U + 00FC。打印字节字符串时,Python将十六进制值81
直接发送到控制台。当印刷Unicode字符串,Python的正确检测我的控制台的编码作为CP437和翻译的Unicode ü为CP437值ü。
这是在UTF-8中声明并保存的文件发生的情况:
├╝ber '\xc3\xbcber'
über u'\xfcber'
在UTF-8中,ü编码为十六进制字节C3 BC
,因此字节字符串包含这些字节,但是Unicode字符串与第一个示例相同。Python读取了两个字节并将其正确解码。Python错误地打印了字节字符串,因为它直接将代表ü的两个UTF-8字节发送到了我的cp437控制台。
在这里,该文件被声明为cp437,但保存在UTF-8中:
├╝ber '\xc3\xbcber'
├╝ber u'\u251c\u255dber'
字节字符串仍然在磁盘上获得了字节(UTF-8十六进制字节C3 BC
),但是将它们解释为两个cp437字符,而不是单个UTF-8编码的字符。转换为Unicode代码点的那两个字符,所有内容打印不正确。
回答 2
那没有设置字符串的格式。它设置文件的格式。即使具有该标头,它"hello"
还是一个字节字符串,而不是Unicode字符串。要使其成为Unicode,您将不得不在u"hello"
任何地方使用它。标头只是在读取.py
文件时使用哪种格式的提示。
回答 3
回答 4
我制作了以下名为unicoder的模块,以便能够对变量进行转换:
import sys
import os
def ustr(string):
string = 'u"%s"'%string
with open('_unicoder.py', 'w') as script:
script.write('# -*- coding: utf-8 -*-\n')
script.write('_ustr = %s'%string)
import _unicoder
value = _unicoder._ustr
del _unicoder
del sys.modules['_unicoder']
os.system('del _unicoder.py')
os.system('del _unicoder.pyc')
return value
然后,您可以在程序中执行以下操作:
# -*- coding: utf-8 -*-
from unicoder import ustr
txt = 'Hello, Unicode World'
txt = ustr(txt)
print type(txt) # <type 'unicode'>