我还在学习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 :(得分:157)
正如其他人所提到的那样,这是两件不同的事情。
当您指定# -*- 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
(如b'These are bytes'
,以声明一个字节序列)。
答案 1 :(得分:22)
正如其他人所说,# 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 :(得分:10)
不设置字符串的格式;它设置文件的格式。即使使用该标头,"hello"
也是字节字符串,而不是Unicode字符串。要使其成为Unicode,您将不得不在任何地方使用u"hello"
。标题只是提示在阅读.py
文件时使用的格式。
答案 3 :(得分:7)
标头定义用于定义代码本身的编码,而不是运行时生成的字符串。
在没有utf-8标头定义的python脚本中放置非ascii字符(如2)会发出警告error http://www.freeimagehosting.net/uploads/1ed15124c4.jpg
答案 4 :(得分:-1)
我制作了以下名为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'>