当python解释器加载源文件时,它会将文件内容转换为内存中的unicode吗?

时间:2017-10-14 08:41:13

标签: python unicode utf-8

说,我有一个用utf8编码的源文件,当python解释器加载该源文件时,它会将文件内容转换为内存中的unicode,然后尝试在unicode中评估源代码吗?

如果我的字符串中包含非ASCII字符,例如

  

astring ='中文'

,文件以gbk编码。

使用python 2运行该文件,我发现字符串实际上仍然是原始的gbk字节。

所以我dboubt,python 2解释不会将源代码转换为unicode。因为如果是这样,字符串内容将是unicode(我听说它实际上是UTF16)

是吗?如果是这样,python 3解释器怎么样?它是否将源代码转换为unicode格式?

实际上,我知道如何在Python2和3中定义unicode和原始字符串。

当解释器加载源代码时,我只是对一个细节感到好奇。

它会在一开始就将WHOLE原始源代码(编码字节)转换为unicode,然后尝试逐个解释unicode格式源代码吗?

或者说,它只是一块一块地加载原始源,并且只解码它认为应该的东西。例如,当它出现在声明中时,中文'好的,解码到unicode。虽然它打击了中文'中文'但是,没有必要解码。

口译员会走哪条路?

3 个答案:

答案 0 :(得分:1)

如果您的源文件使用GBK编码,请将此行放在文件的顶部(第一行或第二行):

# coding: gbk

Python 2和3都需要这样做。 如果省略此编码声明,则解释器将在Python 2中使用ASCII,在Python 3中使用UTF-8。

编码声明控制解释器如何读取源文件的字节。这主要与字符串文字相关(如在您的示例中),但理论上也适用于注释甚至标识符(但在标识符中使用非ASCII可能不是一个好主意。)

至于是否获得字节字符串或unicode字符串的问题:这取决于语法,而不取决于编码的选择和声明。 正如Ignacio的回答所指出的,如果你想在Python 2中使用unicode字符串,你需要使用u'...'表示法。

在Python 3中,u前缀是可选的。 因此,在文件头中使用正确的编码声明,只需编写astring = '中文'就可以在Python 3中获得正确的unicode字符串。

更新

通过评论,OP询问b'中文'的解释。 在Python 3中,这是不允许的(字节字符串只能包含ASCII字符),但您可以在Python 2.x中自己测试:

# coding: gbk
x = b'中文'
y = u'中文'
print repr(x)
print repr(y)

这将产生:

'\xd6\xd0\xce\xc4'
u'\u4e2d\u6587'

第一行反映了源文件中包含的实际字节数(当然,如果使用GBK保存它)。 所以b'中文'似乎没有发生解码。

但是,我不知道解释器如何在内部代表编码方面的源代码(这似乎是你的问题)。 这是依赖于实现的,所以对于cPython,Jython,IronPython等,答案可能会有所不同。

答案 1 :(得分:0)

  

所以我dboubt,python 2解释不会将源代码转换为unicode。

它永远不会。如果要使用Unicode而不是字节,则需要使用unicode代替。

astring = u'中文'

答案 2 :(得分:0)

Python源只是纯ASCII,这意味着实际编码与无关,除了字符串,无论是unicode字符串还是字节字符串。标识符可以使用非ascii字符(恕我直言,这将是一个非常糟糕的做法),但它们的含义通常是Python解释器的内部,因此它读取它们的方式并不重要

字节字符串始终保持不变。这意味着Python 2中的普通字符串和Python 3中的字节字符串永远不会被转换。

始终转换Unicode字符串:

  • 如果特殊字符串coding: charset_name存在于第一行或第二行的注释中,则原始字节字符串将转换为decode(charset_name)
  • 如果没有指定编码,Python 2将假设ASCII,Python 3将假定为utf8