python - 当我在 Python 中使用 open(filename) 或在 C 中使用 fopen(filename) 时,保存文件的编码是什么?

标签 python encoding python-2.7 file-encodings

运行环境:Python 2.7、Windows 7

注意:我说的是PYTHON源代码生成的文件的编码(不是谈论PYTHON源文件的编码),PYTHON源文件顶部声明的编码确实与其中的编码一致PYTHON 源文件已保存。

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

## Author: melo
## Email:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6d1d1f081b041e0402032d04001e1f0e05431906" rel="noreferrer noopener nofollow">[email protected]</a>
## 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)

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

# -*- encoding: gbk -*-
## Author: melo
## Email:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="31414354475842585e5f71585c424352591f455a" rel="noreferrer noopener nofollow">[email protected]</a>
## 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)

有任何证据表明它的行为是这样的吗?

最佳答案

文件以保存的编码保存。源文件以保存的编码保存。它们不必是同样,它们只是应该声明

根据您的other question ,我假设您使用的是 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 字符。

关于python - 当我在 Python 中使用 open(filename) 或在 C 中使用 fopen(filename) 时,保存文件的编码是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12998873/

相关文章:

php - 使用 PHP + MySQL 的 UTF-8 编码问题

python - 如何将 Pandas 数据框的多行标题合并到单个单元格标题中?

python - SQLAlchemy:在回滚无效事务之前无法重新连接

python - 有没有办法在 Python 中编辑包含图像的 xlsx 工作簿?

javascript - 对于 JavaScript 字符串等场景,base128 编码的可行性如何?

c# - 破坏 richtextbox 中的编码

python - 如何在Centos Linux中设置python路径

Python列表在特定条件下选择?

python - 启动时出现 Django runserver 错误

python - Scikit Learn K-means 聚类和 TfidfVectorizer : How to pass top n terms with highest tf-idf score to k-means