Печатать в кодированный файл UTF-8, с перестраиваемыми на платформе символами новой строки?

В 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, но документировано и гарантировано работает?

Ответ 1

Предполагая, что Python 2.7.1 (те документы, которые вы цитировали): Режим "wt" не документирован (режим ONLY, зарегистрированный как "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, с удовольствием сделает это:

[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. Разница заключается в том, что "бильярд в двоичный режим" взлома добавления "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
>>>

Ответ 3

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

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

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