Печатать в файл в кодировке UTF-8 с символами новой строки, зависящими от платформы? - PullRequest
11 голосов
/ 10 мая 2011

В Python, как лучше всего написать файл в кодировке UTF-8 с символами новой строки, зависящими от платформы?в идеале решение должно работать довольно прозрачно в программе, которая много печатает на Python 2. (Информация о Python 3 тоже приветствуется!)

На самом деле, стандартный способ записи в файл UTF-8кажется, codecs.open ('name.txt', 'w') .Однако в документации указано, что

(…) при чтении и записи не выполняется автоматическое преобразование '\ n'.

, поскольку файл фактически открывается в двоичном видеРежим.Итак, как записать в файл UTF-8 с соответствующими символами новой строки, зависящими от платформы?

Примечание. Режим 't', похоже, действительно выполняет свою работу (codecs.open ('name.txt', 'wt')) с Python 2.6 в Windows XP, но задокументировано ли это и гарантированно ли оно работает?

Ответы [ 3 ]

11 голосов
/ 10 мая 2011

Предполагается, что Python 2.7.1 (это документы, которые вы цитировали): режим «wt» не задокументирован (задокументирован только режим «ON» - «r») и не работает - модуль кодеков добавляет «b» крежим, который вызывает его сбой:

>>> f = codecs.open('bar.txt', 'wt', encoding='utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\python27\lib\codecs.py", line 881, in open
    file = __builtin__.open(filename, mode, buffering)
ValueError: Invalid mode ('wtb')

Избегайте модуля кодеков и DIY:

f = open('bar.text', 'w')
f.write(unicode_object.encode('utf8'))

Обновление о Python 3.x:

Похоже, что codecs.open () имеет тот же недостаток (не будет писать ограничитель строки для конкретной платформы).Однако встроенная функция open (), которая имеет encoding arg, рада это сделать:

[Python 3.2 on Windows 7 Pro]
>>> import codecs
>>> f = codecs.open('bar.txt', 'w', encoding='utf8')
>>> f.write('line1\nline2\n')
>>> f.close()
>>> open('bar.txt', 'rb').read()
b'line1\nline2\n'
>>> f = open('bar.txt', 'w', encoding='utf8')
>>> f.write('line1\nline2\n')
12
>>> f.close()
>>> open('bar.txt', 'rb').read()
b'line1\r\nline2\r\n'
>>>

Обновление о Python 2.6

В документации сказанотак же, как 2,7 документов.Разница заключается в том, что попытка «bludgeon in binary mode» добавить «b» в режим arg не удалась в 2.6, поскольку «wtb» не был определен как недопустимый режим, файл был открыт в текстовом режиме и, похоже, работаеткак вы хотели, а не как задокументировано:

>>> import codecs
>>> f = codecs.open('fubar.txt', 'wt', encoding='utf8')
>>> f.write(u'\u0a0aline1\n\xffline2\n')
>>> f.close()
>>> open('fubar.txt', 'rb').read()
'\xe0\xa8\x8aline1\r\n\xc3\xbfline2\r\n' # "works"
>>> f.mode
'wtb' # oops
>>>
4 голосов
/ 10 мая 2011
0 голосов
/ 10 мая 2011

В Python 2, почему бы не кодировать явно?

with open('myfile.txt', 'w') as f:
    print >> f, some_unicode_text.encode('UTF-8')

И встроенные символы новой строки, и те, которые испускаются print, будут преобразованы в соответствующую новую строку платформы.

...