运行环境: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 程序会执行以下操作:
- 如果源文件中使用非 ASCII 字符,请声明源文件的编码。
- 所有文本均使用 Unicode 字符串。
- 在输出到二进制流(例如文件)时对 Unicode 字符串进行编码。
- 从二进制流读取时,将传入的文本数据解码为 Unicode。
- (可选)使用带有字节顺序标记的编码,以便编辑者知道文件编码。
示例:
# 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/