Python 2.6 записывает строку в C-API, используя системную кодировку

У меня есть проект на Python 2.6, и я хотел бы написать сообщение utf-8 на стандартный вывод, используя системную кодировку. Однако похоже, что такой функции не существует до Python 3.2:

PySys_FormatStdout

http://docs.python.org/dev/c-api/sys.html

Есть ли способ сделать это из Python 2.6?

Чтобы уточнить, у меня есть баннер, который нужно распечатать после Py_Initialize() и до запуска основного интерпретатора. Строка представляет собой c-литерал, содержащий: "\n и авторские права \xC2\xA9"

где \xC2\xA9 — это символ авторского права utf-8. Я проверил в gdb, что символ авторского права закодирован правильно.

Обновление: Я просто решил, что все это горе не нужно, и я собираюсь удалить оскорбительный символ из баннера при запуске. С этим слишком много проблем, а документации не хватает. Я ожидал, что это будет похоже на Tcl, где:

  1. C-API встроенного интерпретатора упростит запись stdout в unicode в системной кодировке, а не в кодировке ascii по умолчанию.
  2. Исключение не будет выдано, если в текущей кодировке не существует символа нарушения. Вместо этого будет отображаться некоторый символ замены по умолчанию.
  3. Дополнительные модули (например, sys) не нужно импортировать только для того, чтобы узнать, что такое системная кодировка.

person Juan    schedule 21.12.2010    source источник
comment
1. bugs.python.org/issue4947 (кодировать вручную в Python ‹ 2.7) 2. использовать errors="replace" вместо errors="strict", если нужно 3. PyUnicode_GetDefaultEncoding()   -  person jfs    schedule 23.12.2010
comment
Спасибо J.F., На данный момент я просто собираюсь избегать использования этого персонажа в баннере моего приложения.   -  person Juan    schedule 23.12.2010


Ответы (2)


Вы можете использовать PyFile_WriteObject():

f_stdout = PySys_GetObject("stdout");
text = PyUnicode_DecodeUTF8((char*)str, strlen(str), "strict");
PyFile_WriteObject(text, f_stdout, Py_PRINT_RAW);

Если вы знаете окончательную кодировку, вы можете использовать PyUnicode_AsEncodedString(). .

person jfs    schedule 21.12.2010
comment
Спасибо за ваше предложение. Проблема, которую я получаю сейчас, заключается в том, что она использует ASCII вместо кодировки UTF-8 системы: UnicodeEncodeError: кодек ascii не может кодировать символ u'\xa9' в позиции 80: порядковый номер не в диапазоне (128 ) - person Juan; 21.12.2010
comment
@Juan: что возвращает sys.getdefaultencoding()? - person jfs; 21.12.2010
comment
'ascii', но нужно использовать sys.stdout.encoding, 'utf-8' - person Juan; 22.12.2010
comment
Спасибо J.F. Но мне все еще нужно выяснить, где взять системную кодировку stdout из C-API, не импортируя модуль sys и не вызывая для этого интерпретатор. Думаю, можно с уверенностью предположить, что модуль sys доступен для импорта. - person Juan; 22.12.2010
comment
Отдать это JF, так как он правильно определил это как ошибку. - person Juan; 24.12.2010

PyUnicode_DecodeUTF8()

PyObject_Print()

person Ignacio Vazquez-Abrams    schedule 21.12.2010
comment
Спасибо, мне просто нужно знать, как мне получить ФАЙЛ *, связанный с любыми перенаправлениями stdout человеком, выполняющим интерпретатор Python. - person Juan; 21.12.2010
comment
Вы либо хотите stdout, либо PySys_GetFile("stdout", stdout), в зависимости от того, что вы имеете в виду. тем. - person zwol; 21.12.2010
comment
Я не очень хорошо знаком с работой с файловыми дескрипторами напрямую, но мне просто нужно убедиться, что вещи, которые записываются, идут туда, куда был перенаправлен stdout. - person Juan; 21.12.2010
comment
К сожалению, в строке все мои возвраты каретки экранированы: u'\n--------------------- и она выглядит как какой-то литерал, который войдет в скрипт Python . Кроме того, представляющий интерес символ © записывается как \xa9, что при выводе на экран в моей среде utf-8 должно быть \xc2\xa9. - person Juan; 21.12.2010
comment
sys.stdout может ссылаться на произвольный объект Python (PyObject*) с помощью метода .write(), но PyObject_Print() требует FILE*. - person jfs; 22.12.2010