Senaryo üst kısmında bunu kullanan birkaç py komut dosyaları gördüm. Hangi durumlarda kullanılmalı?
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
Senaryo üst kısmında bunu kullanan birkaç py komut dosyaları gördüm. Hangi durumlarda kullanılmalı?
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
Yanıtlar:
Belgelere göre: Bu, varsayılan ASCII'den, Python çalışma zamanının unicode'a bir dize arabelleğinin kodunu çözmek gerektiğinde kullanacağı UTF-8 gibi diğer kodlamalara geçmenizi sağlar.
Bu işlev yalnızca Python ortamı tararken Python başlatma zamanında kullanılabilir. Sistem çapında bir modülde çağrılmalıdır sitecustomize.py
, Bu modül değerlendirildikten sonra setdefaultencoding()
işlev sys
modülden kaldırılır .
Bunu gerçekten kullanmanın tek yolu, özelliği geri getiren bir yeniden yükleme hack'idir.
Ayrıca, kullanımı sys.setdefaultencoding()
her zaman cesaretini kırmıştır ve py3k'te bir op-haline dönüşmüştür. Py3k kodlaması "utf-8" ile kablolanmıştır ve değiştirilmesi bir hataya neden olur.
Okumak için bazı işaretçiler öneririm:
sys.stdout
bir olduğunda None
bir Python programının çıkışını yönlendirme yaparken gibi kodlama).
sys.setdefaultencoding()
her zaman cesaret kırıldı"
UTF-8
. LC_ALL=en_US.UTF-8 python3 -c 'import sys; print(sys.stdout.encoding)'
verir UTF-8
ama LC_ALL=C python3 -c 'import sys; print(sys.stdout.encoding)'
verir ANSI_X3.4-1968
(ya da belki başka bir şey)
Cevap ASLA değil ! (ne yaptığınızı gerçekten bilmiyorsanız)
9/10 kez çözüm, uygun kodlama / kod çözme anlayışı ile çözülebilir.
1/10 kişinin yanlış tanımlanmış bir yerel ayarı veya ortamı vardır ve şunları ayarlaması gerekir:
PYTHONIOENCODING="UTF-8"
ortamlarında konsol yazdırma sorunlarını gidermek için.
(yeniden kullanmaktan kaçınmak için), Python 2.x'in bir Unicode'u () bir str () 'e (ve tersi) dönüştürmesi gerektiğinde kullanılan varsayılan kodlama / kod çözmeyi değiştirir ve kodlama verilmez. yani:sys.setdefaultencoding("utf-8")
str(u"\u20AC")
unicode("€")
"{}".format(u"\u20AC")
Python 2.x'te, varsayılan kodlama ASCII olarak ayarlanmıştır ve yukarıdaki örnekler aşağıdakilerle başarısız olacaktır:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)
(Konsolum UTF-8 olarak yapılandırıldı, bu "€" = '\xe2\x82\xac'
nedenle istisna açık \xe2
)
veya
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
bunların benim için çalışmasına izin verecek , ancak UTF-8 kullanmayan kişiler için çalışmayabilir. Varsayılan ASCII, kodlama varsayımlarının koda dönüştürülmemesini sağlarsys.setdefaultencoding("utf-8")
sys.setdefaultencoding("utf-8")
sys.stdout.encoding
karakterleri konsola yazdırırken kullanılan, düzeltmek gibi görünen bir yan etkisi de vardır . Python bunu ayarlamak için kullanıcının yerel ayarını (Linux / OS X / Un * x) veya kod sayfasını (Windows) kullanır. Bazen bir kullanıcının yerel ayarı bozulur ve yalnızca konsol kodlamasınıPYTHONIOENCODING
düzeltmek gerekir .
Misal:
$ export LANG=en_GB.gibberish
$ python
>>> import sys
>>> sys.stdout.encoding
'ANSI_X3.4-1968'
>>> print u"\u20AC"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
>>> exit()
$ PYTHONIOENCODING=UTF-8 python
>>> import sys
>>> sys.stdout.encoding
'UTF-8'
>>> print u"\u20AC"
€
İnsanlar 16 yıldır Python 2.x'e karşı varsayılan kodlamanın ASCII olduğunu anlıyorlar. UnicodeError
ASCII dışı içerdiği belirlenen dizelerdeki Unicode dönüşümlerini dizeye işlemek için kural dışı durum işleme yöntemleri yazılmıştır.
Gönderen https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/
def welcome_message(byte_string):
try:
return u"%s runs your business" % byte_string
except UnicodeError:
return u"%s runs your business" % unicode(byte_string,
encoding=detect_encoding(byte_string))
print(welcome_message(u"Angstrom (Å®)".encode("latin-1"))
Varsayılan kodlamayı ayarlamadan önce bu kod, ascii kodlamasındaki “Å” kodunun kodunu çözemez ve kodlamayı tahmin etmek ve düzgün bir şekilde unicode'a dönüştürmek için istisna işleyicisine girerdi. Yazdırma: Angstrom (Å®) işinizi yürütür. Varsayılan kodlamayı utf-8 olarak ayarladıktan sonra kod, byte_string öğesinin utf-8 olarak yorumlanabildiğini görür ve böylece verileri değiştirir ve bunun yerine bunu döndürür: Angstrom (Ů) işinizi yürütür.
Sabit olması gereken şeyi değiştirmek, bağımlı olduğunuz modüller üzerinde dramatik etkiler yaratacaktır. Kodunuza girip çıkan verileri düzeltmek daha iyidir.
Varsayılan kodlamanın UTF-8 olarak ayarlanması, aşağıdaki örnekte temel neden olmasa da, sorunların nasıl maskelentiğini ve giriş kodlaması değiştiğinde, kodun açık bir şekilde nasıl bozulduğunu gösterir: UnicodeDecodeError: 'utf8' codec bileşeni 3131 konumundaki bayt 0x80 kod çözme: geçersiz başlangıç baytı
sys.setdefaultencoding("utf-8")
da, kodun Python 3 gibi daha iyi davranması iyidir. 2017 şimdi. Cevabı 2015 yılında geri yazsanız bile, geriye bakmak yerine dört gözle beklemek daha iyi olduğunu düşünüyorum. Aslında benim için en basit çözüm, kodumun yeniden yönlendirilip yönlendirilmemesine (Python 2 için çok kötü bir sorun) bağlı olarak Python 2'de farklı davrandığını bulduğumda. Söylemeye gerek yok, ben zaten var # coding: utf-8
ve Python 3 için herhangi bir geçici çözüm gerekmez (aslında setdefaultencoding
kullanarak sürüm denetimi maskelemek zorunda ).
sys.setdefaultencoding("utf-8")
Py 2.x kodunuzu Python 3 ile uyumlu hale getirmiyor. Varsayılan kodlamanın ASCII olduğunu varsayan harici modülleri de düzeltmiyor. Kodunuzu Python 3 uyumlu hale getirmek çok basittir ve bu kötü hack gerektirmez. Örneğin, bunun neden çok gerçek sorunlara neden olduğunu, Amazon ile bu varsayımla uğraştığım deneyime bakın: stackoverflow.com/questions/39465220/…
PYTHONIOENCODING="UTF-8"
Python2.7 Django-1.11 ortamına yardımcı oldu. Teşekkürler.
detect_encoding
.
detect_encoding
, ipuçlarına dayalı bir dizenin kodlamasını algılayabilen bir yöntem olduğunu düşünün .
#!/usr/bin/env python
#-*- coding: utf-8 -*-
u = u'moçambique'
print u.encode("utf-8")
print u
chmod +x test.py
./test.py
moçambique
moçambique
./test.py > output.txt
Traceback (most recent call last):
File "./test.py", line 5, in <module>
print u
UnicodeEncodeError: 'ascii' codec can't encode character
u'\xe7' in position 2: ordinal not in range(128)
kabuk üzerinde çalışır, sdtout'a gönderme değil, bu yüzden stdout'a yazmak için bir çözüm var.
Sys.stdout.encoding tanımlanmamışsa veya başka bir deyişle, stdout'a yazmak için önce PYTHONIOENCODING = UTF-8 dışa aktarmaya ihtiyaç duyulduğunda çalıştırılmayan başka bir yaklaşım yaptım.
import sys
if (sys.stdout.encoding is None):
print >> sys.stderr, "please set python env PYTHONIOENCODING=UTF-8, example: export PYTHONIOENCODING=UTF-8, when write to stdout."
exit(1)
yani, aynı örneği kullanarak:
export PYTHONIOENCODING=UTF-8
./test.py > output.txt
çalışacak
İlk tehlike yatıyor reload(sys)
.
Bir modülü yeniden yüklediğinizde, aslında çalışma sürenizde modülün iki kopyasını alırsınız . Eski modül, diğer her şey gibi bir Python nesnesidir ve referansları olduğu sürece hayatta kalır. Böylece, nesnelerin yarısı eski modüle, yarısı da yeni modüle işaret edecek. Bazı değişiklikler yaptığınızda, bazı rastgele nesneler değişikliği görmediğinde hiçbir zaman geleceğini görmezsiniz:
(This is IPython shell)
In [1]: import sys
In [2]: sys.stdout
Out[2]: <colorama.ansitowin32.StreamWrapper at 0x3a2aac8>
In [3]: reload(sys)
<module 'sys' (built-in)>
In [4]: sys.stdout
Out[4]: <open file '<stdout>', mode 'w' at 0x00000000022E20C0>
In [11]: import IPython.terminal
In [14]: IPython.terminal.interactiveshell.sys.stdout
Out[14]: <colorama.ansitowin32.StreamWrapper at 0x3a9aac8>
Şimdi, sys.setdefaultencoding()
uygun
Etkilediği tek şey örtük dönüşümdürstr<->unicode
. Şimdi, utf-8
gezegendeki en san kodlama (ASCII ve hepsi ile geriye dönük uyumlu), dönüşüm şimdi "sadece çalışıyor", ne yanlış gidebilir?
Şey, her şey. Ve bu tehlike.
UnicodeError
ASCII olmayan giriş için atılana dayanan veya şimdi bir beklenmedik sonuç üreten bir hata işleyici ile kod dönüştürme yapan bazı kodlar olabilir . Ve tüm kodlar varsayılan ayar ile test edildiğinden, kesinlikle burada "desteklenmeyen" bölgede bulunuyorsunuz ve hiç kimse size kodlarının nasıl davranacağını garanti etmiyor.