Запись Unicode Python в файл падает в командной строке, но не в IDE - PullRequest
2 голосов
/ 22 марта 2012

У меня проблема с тем, что мой код Python 2.7.3rc2 нормально работает через IDE (Aptana Studio 3 с PyDev), но вылетает, когда я дважды щелкаю по файлу .py или пытаюсь запустить его из команды Windowsline.

Проблема в том, что я пытаюсь записать в файл строку, содержащую символы Юникода.В среде IDE с этим нет проблем, и файл правильно записывается с использованием символов Юникода.Версия из командной строки жалуется на то, что не может кодировать определенные символы.

Корень вопроса в том, что отличается в версии IDE от версии для командной строки в том, что один записывает файл в формате Unicode правильно, а другой - нет.?

Идеальное решение должно иметь версию командной строки, работающую точно так же, как и версия IDE.


РЕДАКТИРОВАТЬ: Извините, я думал, что предполагалось, какая командаЯ использовал для записи строки в файл, но я новичок в Python.Фактическая команда write() вызывается для объекта f, для которого был создан экземпляр f = open(path, 'w').Я передаю ему строку, которую хочу записать в файл, и эта строка содержит символы Юникода.

Полное сообщение об ошибке:

Traceback (most recent call last):
  File "writer.py", line 46, in <module>
    write_listings(c, output_path)
  File "writer.py", line 33, in write_listings
    print name
  File "c:\Python27\lib\encodings\cp437.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 21-26: character maps to <undefined>

Вот пример строки: 滑鐵盧安大略加拿大

К сожалению, у меня возникают проблемы при создании SSCCE, потому что я не могу просто поместить этот строковый литерал в файл исходного кода, не пожаловавшись на то, что я не объявил кодировку.Это расстраивает - все работало так хорошо, когда я запускал все из IDE, и теперь я направляюсь в кроличью нору с юникодом!

EDIT : Спасибо Фредрику, ятеперь в состоянии сделать SSCCE.Вот оно:

# -*- coding: utf-8 -*-
str = u'滑鐵盧安大略加拿大'
f = open('test', 'w')
f.write(str)
f.close()

Этот SSCCE аварийно завершает работу при запуске из командной строки, но не из IDE. Почему это так?

EDIT : я добавил дополнительный код, предложенный Эдвардом Лопером, чтобы убедиться, что версия Python идентична для командной строки и версий IDE.

Вот новый код:

# -*- coding: utf-8 -*-
import sys
print sys.version
print open
print open.__module__

str = u'滑鐵盧安大略加拿大'
f = open('test', 'w')
f.write(str)
f.close()

Вот вывод при запуске из IDE:

2.7.3rc2 (default, Mar 18 2012, 22:59:27) [MSC v.1500 64 bit (AMD64)]
<built-in function open>
__builtin__

А вот вывод при запуске из командыline:

2.7.3rc2 (default, Mar 18 2012, 22:59:27) [MSC v.1500 64 bit (AMD64)]
<built-in function open>
__builtin__
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    f.write(str)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-8: ordinal not in range(128)

На мой взгляд, вопрос до сих пор остается без ответа, потому что я до сих пор не представляю, как это работает в IDE, а не в командной строке!

Ответы [ 3 ]

3 голосов
/ 22 марта 2012

Вы должны явно закодировать вашу строку в желаемой кодировке перед записью в файл:

f.write(text.encode("cp1250", "replace")) # Czech Windows encoding, use your own

или

f.write(text.encode("utf-8", "replace")) # UTF-8

Вы также можете явно открыть файл с определенной кодировкой:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import codecs

x = "abcč"
f = codecs.open("test.txt", "w", "utf-8", "replace")
f.write(x)
1 голос
/ 22 марта 2012

Как сказал Фениксо, вы должны закодировать строку перед записью в файл. Причина, по которой file.write () не делает этого сама по себе, заключается в том, что вам нужно указать, какую кодировку (utf-8, utf-16 и т. Д.) Вы хотите использовать. Есть модуль Python «кодеки», который позволяет создавать потоковые объекты, которые знают, какую кодировку использовать, и автоматически применяют ее. Это то, что Фениксо использует во втором примере.

Что касается того, почему ваш код работает в IDE, а не в командной строке, я предполагаю, что ваша IDE устанавливает "кодировку по умолчанию" на некоторое значение, отличное от значения по умолчанию. Попробуйте запустить это как в среде IDE, так и в командной строке, и посмотрите, отличается ли она:

>>> import sys
>>> print sys.getdefaultencoding()

Вот некоторая связанная информация: http://blog.ianbicking.org/illusive-setdefaultencoding.html

1 голос
/ 22 марта 2012

Это то, что я делаю, когда мне нужно работать с определенной кодировкой

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import codecs
out = codecs.getwriter('utf-8')(sys.stdout)
out.write('some åäö-string')
...