Comment puis-je faire python 3 (3.1) print("Some text")
pour stdout en UTF-8, ou comment sortir des octets bruts?
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)
Sortie (dans CP1257 et j'ai remplacé les caractères par des valeurs d'octet [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
est tout simplement trop intelligent ...: D Cela ne sert à rien d'utiliser du texte codé avec print
(car il n'affiche toujours que la représentation des octets et non des octets réels) et il est impossible de produire des octets du tout, car imprimez quand même et toujours l'encode en sys.stdout.encoding
.
Par exemple: print(chr(255))
renvoie une erreur:
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>
Par ailleurs, print( TestText == TestText2.decode("utf8"))
renvoie False
, bien que la sortie d'impression soit la même.
Comment Python 3 détermine-t-il sys.stdout.encoding
Et comment puis-je le changer?
J'ai créé une fonction printRAW()
qui fonctionne très bien (en fait, elle code la sortie en UTF-8, donc vraiment ce n'est pas brut ...):
def printRAW(*Text):
RAWOut = open(1, 'w', encoding='utf8', closefd=False)
print(*Text, file=RAWOut)
RAWOut.flush()
RAWOut.close()
printRAW("Cool", TestText)
Sortie (maintenant imprimée en UTF-8):
Cool Test - āĀēĒčČ..šŠūŪžŽ
printRAW(chr(252))
imprime également bien ü
(en UTF-8, [xC3][xBC]
) et sans erreur :)
Maintenant, je cherche peut-être une meilleure solution s'il y en a ...
Tout d'abord, une correction:
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.
Maintenant, pour envoyer UTF-8 vers stdout, quel que soit l'encodage de la console, utilisez le bon outil pour le travail:
import sys
sys.stdout.buffer.write(TestText2)
"buffer" est une interface brute vers stdout.
C'est le meilleur que je puisse me sortir du manuel, et c'est un peu un hack sale:
utf8stdout = open(1, 'w', encoding='utf-8', closefd=False) # fd 1 is stdout
print(whatever, file=utf8stdout)
Il semble que les objets fichier devraient avoir une méthode pour changer leur encodage, mais AFAICT il n'y en a pas.
Si vous écrivez dans utf8stdout puis écrivez dans sys.stdout sans appeler utf8stdout.flush () en premier, ou vice versa, de mauvaises choses peuvent se produire.