Birincisi: reload(sys)
ve sadece bir çıkış terminali akışı ihtiyacı ile ilgili bazı rastgele varsayılan kodlamaların yapılması kötü bir uygulamadır. reload
genellikle çevreye bağlı olarak yerleştirilen sys öğelerini değiştirir - örneğin sys.stdin / stdout akışları, sys.excepthook, vb.
Stdout'ta kodlama problemini çözme
print
Sys.stdout str
' unicode dizeleri ve ötesinde ascii ' s (örneğin değişmez) gelen kodlama sorunu çözmek için bildiğim en iyi çözüm : yetenekli ve sys.stdout (dosya benzeri bir nesne) dikkat etmektir ihtiyaca göre toleranslı:
Ne zaman sys.stdout.encoding
olduğunu None
nedense veya mevcut olmayan ya da hatalı yanlış veya neler yapabileceğini stdout'u terminali ya gerçekten akışı daha "az" o zaman doğru sağlamaya çalışıyoruz .encoding
niteliği. Sonunda sys.stdout & sys.stderr
, çeviri yapan dosya benzeri bir nesne ile değiştirerek.
Terminal / akış hala var olan tüm unicode karakterleri kodlayamadığında ve print
sadece bu nedenle kırılmak istemediğinizde , çeviri dosyası benzeri nesnede değiştirilen bir kodla davranışı ekleyebilirsiniz.
İşte bir örnek:
#!/usr/bin/env python
# encoding: utf-8
import sys
class SmartStdout:
def __init__(self, encoding=None, org_stdout=None):
if org_stdout is None:
org_stdout = getattr(sys.stdout, 'org_stdout', sys.stdout)
self.org_stdout = org_stdout
self.encoding = encoding or \
getattr(org_stdout, 'encoding', None) or 'utf-8'
def write(self, s):
self.org_stdout.write(s.encode(self.encoding, 'backslashreplace'))
def __getattr__(self, name):
return getattr(self.org_stdout, name)
if __name__ == '__main__':
if sys.stdout.isatty():
sys.stdout = sys.stderr = SmartStdout()
us = u'aouäöüфżß²'
print us
sys.stdout.flush()
Python 2/2 + 3 kodunda ascii düz dize değişmezlerini kullanma
Küresel varsayılan kodlama değiştirmek için tek iyi neden (sadece UTF-8 için) Ben bir uygulama kaynak kodu kararı ile ilgili olduğunu düşünüyorum - I / O akışı kodlama sorunları nedeniyle değil: zorla olmadan ascii dize değişmezleri koda kod yazmak için her zaman u'string'
unicode kaçış tarzı kullanmak için . Bu, ascii veya UTF-8 düz dize değişmez değerlerini sürekli olarak kullanan bir Python 2 veya Python 2 + 3 kaynak kodu temeline dikkat ederek tutarlı bir şekilde ( anonbadger'ın makalesine rağmen ) yapılabilir. Unicode dönüştürme ve modüller arasında hareket veya potansiyel olarak stdout gidin. Bunun için "# encoding: utf-8
"veya ascii (bildirim yok). chr # 127 (bugün nadir olan) ötesinde ascii varsayılan kodlama hatalarına hala çok aptalca bir şekilde dayanan kütüphaneleri değiştirin veya bırakın.
Ve SmartStdout
yukarıdaki şemaya ek olarak uygulama başlangıcında (ve / veya sitecustomize.py aracılığıyla) bunu kullanmadan yapın reload(sys)
:
...
def set_defaultencoding_globally(encoding='utf-8'):
assert sys.getdefaultencoding() in ('ascii', 'mbcs', encoding)
import imp
_sys_org = imp.load_dynamic('_sys_org', 'sys')
_sys_org.setdefaultencoding(encoding)
if __name__ == '__main__':
sys.stdout = sys.stderr = SmartStdout()
set_defaultencoding_globally('utf-8')
s = 'aouäöüфżß²'
print s
Bu şekilde dize değişmezleri ve çoğu işlem (karakter yineleme hariç), yalnızca Python3 gibi, unicode dönüşümü hakkında düşünmeden rahat çalışır. Dosya I / O, elbette Python3'te olduğu gibi kodlamalar konusunda her zaman özel bakıma ihtiyaç duyar.
Not: ovalar dizeleri daha sonra SmartStdout
çıkış akımının muhafazasına dönüştürülmeden önce utf-8'den unicode'a dönüştürülür.