2

运行时环境:Python 2.7、Windows 7

注意:我说的是 PYTHON 源代码生成的文件的编码(不是说 PYTHON 源文件的编码),PYTHON 源文件顶部声明的编码确实与 PYTHON 源文件的编码一致得救了。

当 string() 中没有非 ascii 字符时content = 'abc',文件( file.txt,而不是 PYTHON 源文件)在 之后以 ANSI 编码保存fp.close(),PYTHON 文件(并以 ANSI 编码格式保存)内容如下:

## Author: melo
## Email:prevision@imsrch.tk
## Date: 2012/10/12
import os

def write_file(filepath, mode, content):
    try:
        fp = open(filepath, mode)
        try:
            print 'file encoding:', fp.encoding
            print 'file mode:', fp.mode
            print 'file closed?', fp.closed
            fp.write(content)
        finally:
            fp.close()
            print 'file closed?', fp.closed
    except IOError, e:
        print e


if __name__ == '__main__':
    filepath = os.path.join(os.getcwd(), 'file.txt')
    content = 'abc'
    write_file(filepath, 'wb', content)

但是当 string() 中有一些非 ascii 字符时content = 'abc莹',file( file.txt) 将在 之后以 UTF-8 编码保存,尽管我在 PYTHON 源文件(不是)fp.close()的顶部声明了编码。此时,PYTHON 源文件的内容如下:file.txt#encoding=gbk

# -*- encoding: gbk -*-
## Author: melo
## Email:prevision@imsrch.tk
## Date: 2012/10/12
import os

def write_file(filepath, mode, content):
    try:
        fp = open(filepath, mode)
        try:
            print 'file encoding:', fp.encoding
            print 'file mode:', fp.mode
            print 'file closed?', fp.closed
            fp.write(content)
        finally:
            fp.close()
            print 'file closed?', fp.closed
    except IOError, e:
        print e

if __name__ == '__main__':
    filepath = os.path.join(os.getcwd(), 'file.txt')
    content = 'abc莹'
    write_file(filepath, 'wb', content)

有没有证据表明它的行为是这样的?

4

2 回答 2

3

文件以保存它的编码保存。源文件以保存它的编码保存。它们不必相同,只需声明它们。

根据您的其他问题,我假设您使用的是 Notepad++,当您打开时,file.txt您发现 Notepad++ 认为该文件是以UTF-8 without BOM. 这是 Notepad++ 的错误猜测。选择中文GB2312字符集,文件将正常显示。

除非通过字节顺序标记 (BOM) 或其他一些元数据给出提示或由用户告知,否则程序不知道文件的编码方式。

一个正确的 Python 程序会做这些事情:

  1. 如果源文件中使用了非 ASCII 字符,则声明源文件的编码。
  2. 对所有文本使用 Unicode 字符串。
  3. 输出到文件等二进制流时对 Unicode 字符串进行编码。
  4. 从二进制流中读取时,将传入的文本数据解码为 Unicode。
  5. (可选)使用带有字节顺序标记的编码,以便编辑者知道文件编码。

例子:

# encoding: utf-8
import codecs
with codecs.open('file.txt','wb',encoding='utf-8-sig') as f:
    f.write(u'abc莹')

您现在应该在 Notepad++ 中看到file.txt被检测为编码为“UTF-8”(带有 BOM)并正确显示文件。

请注意,如果您将编码声明为gbk,则可以将文件保存为“ANSI”(系统上的 GBK),并且由于使用了 Unicode 字符串,它仍然可以工作。

实际上,您的系统可能是代码页 936 ( cp936) 而不是 GBK。它们并不完全相同。最好使用 UTF-8 或 UTF-16 之类的 Unicode 编码,它们可以准确地表示所有 Unicode 字符。

于 2012-10-21T15:17:27.710 回答
1
# -*- encoding: gbk -*-

在 PYTHON 文件的顶部,指示 PYTHON 文件的编码。要使用编解码器,请使用编解码器模块。

你需要这个:codecs.open()

于 2012-10-21T14:47:37.997 回答