Soru Python 3 baskı () utf8 nasıl yapılır


Python'u nasıl yapabilirim 3 (3.1) print("Some text") UTF-8'de stdout'a mı, yoksa ham baytların nasıl çıkarılacağına?

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)

Çıktı (CP1257'de ve char'ları bayt değerlerine değiştirdim [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 sadece çok akıllı ...: D ile kodlanmış metin kullanarak hiçbir nokta print (her zaman sadece baytların gerçek baytlarının gösterimini gösterdiği için) ve bayt çıkışı hiç de imkansızdır, çünkü zaten yazdırır ve her zaman bunu kodlar. sys.stdout.encoding.

Örneğin: print(chr(255)) bir hata atar:

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>

Bu arada print( TestText == TestText2.decode("utf8")) döner FalseHer ne kadar baskı çıkışı aynı olsa da.


Python 3 nasıl belirlenir sys.stdout.encoding ve onu nasıl değiştirebilirim?

Ben yaptım printRAW() iyi çalışıyor fonksiyonu (aslında UTF-8 çıkışını kodlar, bu yüzden gerçekten ham değil ...):

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

 printRAW("Cool", TestText)

Çıktı (şimdi UTF-8'de yazdırılıyor):

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

printRAW(chr(252)) ayrıca güzel baskılar ü (UTF-8'de, [xC3][xBC]) ve hatasız :)

Şimdi, belki de daha iyi bir çözüm arıyorsanız ...


32
2017-08-30 02:26


Menşei


Kontrol bu dışarıda. - Soorena


Cevaplar:


İlk olarak, bir düzeltme:

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.

Artık, konsolun kodlamasından bağımsız olarak, UTF-8'i stdout'a göndermek için, iş için doğru aracı kullanın:

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

"buffer", stdout'un ham arayüzüdür.


43
2017-08-30 18:31



teşekkürler :) dediğim zaman: "Test - āĀēĒčČ..šŠūŪžŽ" # bu UTF-8 Bu dizinin IDE ile UTF-8 ile yazıldığını, py dosyasının UTF-8 ile kodlandığını ve python'un dosyayı ayrıştırdığını string'i Python unicode'a dönüştürür ... - davispuh
Alıyorum: Traceback (son çağrı son): Dosya "<stdin>", satır 1, <modül> AttributeError: '_ReplOutput' nesnesinde 'buffer' özniteliği yok - eyaler
Python 3? IDE kullanıyor musunuz? _ReplOutput, stdout'un (yanlış) dosya benzeri bir nesne ile değiştirildiğine benziyor. - Mark Tolonen
(Tamam, mücadele rağmen ben çok satırlı hata msg gönderemiyorum) Hmm ... >>> sys.stdout.buffer (). Yazma (chr (255)) Traceback (son çağrı son): Dosya "<stdin> ", satır 1, <modül> TypeError: '_io.BufferedWriter' nesnesi callable değil >>> sys.stdout.buffer.write (chr (252)) Traceback (son çağrı son): Dosya" <stdin> " , satır 1, <modül> TypeError: 'str', Python 3.2.2 tampon arabirimini desteklemiyor - Van Jone
@VanJone, yeni bir soru gönderin. - Mark Tolonen


Bu, el kitabından çıkardığım en iyi şey ve biraz kirli bir hack:

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

Dosya nesneleri kodlamalarını değiştirmek için bir yönteme sahip gibi görünüyor, ancak AFAICT yoktur.

Eğer utf8stdout'a yazarsanız ve sonra utf8stdout.flush () 'i çağırmadan sys.stdout'a yazarsanız, ya da tam tersi, kötü şeyler olabilir.


13
2017-08-30 04:20



Pencerelerde sorun vardı, nerede cp1257 İstediğim sırada baskı (ve başarısız) için kullanıldı utf-8. Aşağıdaki snippet çalıştı: import sys; sys.stdout = open(1, 'w', encoding='utf-8', closefd=False); print("vadsэавфыаЭХÜÜÄ"); print(bytes("аЭХÜ", "utf-8")) - iljau
@zwol ve hepsi: Python 3'ün mantığı nedir print işlev Unicode işlemek için tanımlanmış ve tasarlanmış mı? - Old Geezer
@OldGeezer Bu doğru değil. O oldu Unicode işlemek için tasarlanmış ve tasarlanmış. Ama tercüman, bir sebepten dolayı, muhtemelen asla bilmeyeceğimizi düşünüyor. sys.stdoutbir terminal emülatöre besleniyor değil Unicode, sadece CP1257 işlemek ve bu nedenle print (aslında sys.stdout.write) dönüştürmeli itibaren Unicode için CP1257 yazdırmadan önce ve CP1257 repertuarında olmayan herhangi bir karakter basılamaz. print senin için yapmayacağım). - zwol