Как сделать python 3 print() utf8

Как я могу сделать python 3 (3.1) print("Some text") в stdout в UTF-8 или как выводить необработанные байты?

Test.py

TestText = "Test - āĀēĒčČ..šŠūŪžŽ" # this is UTF-8
TestText2 = b"Test2 - \xc4\x81\xc4\x80\xc4\x93\xc4\x92\xc4\x8d\xc4\x8c..\xc5\xa1\xc5\xa0\xc5\xab\xc5\xaa\xc5\xbe\xc5\xbd" # just bytes
print(sys.getdefaultencoding())
print(sys.stdout.encoding)
print(TestText)
print(TestText.encode("utf8"))
print(TestText.encode("cp1252","replace"))
print(TestText2)

Выход (в CP1257 и я заменил символы на байтовые значения [x00]):

utf-8
cp1257
Test - [xE2][xC2][xE7][C7][xE8][xC8]..[xF0][xD0][xFB][xDB][xFE][xDE]  
b'Test - \xc4\x81\xc4\x80\xc4\x93\xc4\x92\xc4\x8d\xc4\x8c..\xc5\xa1\xc5\xa0\xc5\xab\xc5\xaa\xc5\xbe\xc5\xbd'
b'Test - ??????..\x9a\x8a??\x9e\x8e'
b'Test2 - \xc4\x81\xc4\x80\xc4\x93\xc4\x92\xc4\x8d\xc4\x8c..\xc5\xa1\xc5\xa0\xc5\xab\xc5\xaa\xc5\xbe\xc5\xbd'

print слишком умен...: D Нет смысла использовать кодированный текст с print (так как он всегда показывает только представление байтов не реальных байтов), и вообще невозможно выводить байты, потому что печать в любом случае и всегда кодирует его в sys.stdout.encoding.

Например: print(chr(255)) выдает сообщение об ошибке:

Traceback (most recent call last):
  File "Test.py", line 1, in <module>
    print(chr(255));
  File "H:\Python31\lib\encodings\cp1257.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\xff' in position 0: character maps to <undefined>

Кстати, print( TestText == TestText2.decode("utf8")) возвращает False, хотя вывод печати одинаков.


Как Python 3 определяет sys.stdout.encoding и как его изменить?

Я создал функцию printRAW(), которая отлично работает (на самом деле она кодирует вывод в UTF-8, так что действительно это не raw...):

 def printRAW(*Text):
     RAWOut = open(1, 'w', encoding='utf8', closefd=False)
     print(*Text, file=RAWOut)
     RAWOut.flush()
     RAWOut.close()

 printRAW("Cool", TestText)

Выход (теперь он печатается в UTF-8):

Cool Test - āĀēĒčČ..šŠūŪžŽ

printRAW(chr(252)) также прекрасно печатает ü (в UTF-8, [xC3][xBC]) и без ошибок:)

Теперь я ищу, может быть, лучшее решение, если есть...

Ответ 1

Во-первых, исправление:

TestText = "Test - āĀēĒčČ..šŠūŪžŽ" # this NOT utf-8...it is a Unicode string in Python 3.X.
TestText2 = TestText.encode('utf8') # THIS is "just bytes" in UTF-8.

Теперь, чтобы отправить UTF-8 в stdout, независимо от консольной кодировки, используйте правильный инструмент для задания:

import sys
sys.stdout.buffer.write(TestText2)

"buffer" - это исходный интерфейс для стандартного вывода.

Ответ 2

Это лучшее, что я могу извлечь из руководства, и это немного грязный взлом:

utf8stdout = open(1, 'w', encoding='utf-8', closefd=False) # fd 1 is stdout
print(whatever, file=utf8stdout)

Кажется, что у файловых объектов должен быть способ изменения их кодировки, но AFAICT не существует.

Если вы пишете utf8stdout, а затем напишите в sys.stdout, не вызвав сначала utf8stdout.flush(), или наоборот, могут возникнуть плохие вещи.