В какой кодировке сохраняется файл, когда я использую 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 будет делать эти вещи:

  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" (с спецификацией) и правильно отображает файл.

Обратите внимание, что вы можете сохранить файл в формате "ANSI" (GBK в вашей системе), если вы объявите кодировку как gbk и все равно будет работать, потому что были использованы строки Unicode.

На самом деле, ваша система, вероятно, кодовая страница 936 (cp936) вместо ГБК. Они не совсем одинаковые. Лучше использовать кодировку Unicode, например UTF-8 или UTF-16, которая может точно представлять все символы Unicode.

# -*- encoding: gbk -*-

вверху файла PYTHON указывает кодировку файла PYTHON. для работы с кодеками используйте модуль кодеков.

ты нуждаешься в этом: codecs.open()

Другие вопросы по тегам