В какой кодировке сохраняется файл, когда я использую open(имя файла) в Python или fopen(имя файла) в C?
Среда выполнения: Python 2.7, Windows 7
ПРИМЕЧАНИЕ. Я говорю о кодировке файла, сгенерированного исходным кодом PYTHON (НЕ говоря о кодировке исходного файла PYTHON), кодировка, объявленная в верхней части исходного файла PYTHON, DID согласуется с кодировкой, в которой исходный файл PYTHON был сохранен
Если в строке нет символов, отличных от 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)
но когда в строке есть не-ascii символы (content = 'abc莹'
), файл(file.txt
) будет сохранен в кодировке UTF-8 после fp.close()
, хотя я объявил кодировку в верхней части исходного файла PYTHON (не file.txt
) с #encoding=gbk
, В настоящее время содержимое исходного файла PYTHON выглядит следующим образом:
# -*- 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)
Есть ли доказательства того, что он так себя ведет?
2 ответа
Файл сохраняется в кодировке, в которой вы его сохраняете. Исходный файл сохраняется в кодировке, в которой вы его сохраняете. Они не должны быть одинаковыми, они просто должны быть объявлены.
На ваш другой вопрос, я предполагаю, что вы используете 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" (с спецификацией) и правильно отображает файл.
Обратите внимание, что вы можете сохранить файл в формате "ANSI" (GBK в вашей системе), если вы объявите кодировку как gbk
и все равно будет работать, потому что были использованы строки Unicode.
На самом деле, ваша система, вероятно, кодовая страница 936 (cp936
) вместо ГБК. Они не совсем одинаковые. Лучше использовать кодировку Unicode, например UTF-8 или UTF-16, которая может точно представлять все символы Unicode.
# -*- encoding: gbk -*-
вверху файла PYTHON указывает кодировку файла PYTHON. для работы с кодеками используйте модуль кодеков.
ты нуждаешься в этом: codecs.open()