В Python 2 есть строки в юникоде и строки байтов. Если вы просто используете строки байтов, вы можете читать / записывать в файл, открытый с open()
. В конце концов, строки - это просто байты.
Проблема возникает, когда, скажем, у вас есть строка Unicode, и вы делаете следующее:
>>> example = u'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
Так что здесь, очевидно, вы либо явно кодируете свою строку юникода в utf-8, либо используете codecs.open
, чтобы сделать это для вас прозрачно.
Если вы когда-либо используете только строки байтов, тогда никаких проблем:
>>> example = 'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
>>>
Это становится более сложным, чем это, потому что, когда вы объединяете юникод и строку байтов с помощью оператора +
, вы получаете строку юникода. Легко быть укушенным этим.
Также codecs.open
не нравятся строки байтов с передаваемыми в ASCII символами:
codecs.open('test', 'w', encoding='utf-8').write('Μου αρέσει')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/codecs.py", line 691, in write
return self.writer.write(data)
File "/usr/lib/python2.7/codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
Совет по строкам для ввода / вывода обычно «конвертирует в юникод как можно раньше, а обратно в байтовые строки как можно позже». Использование codecs.open
позволяет сделать это очень легко.
Только будьте осторожны с тем, что вы даете ему строки в юникоде, а не строки байтов, которые могут содержать символы не-ASCII.