Article View: pl.comp.lang.python
Article #27529Re: String, unicode, dziwny problem i 5 pytań - długie
From: marrgol
Date: Fri, 18 Jun 2010 23:36
Date: Fri, 18 Jun 2010 23:36
95 lines
4537 bytes
4537 bytes
On 2010-06-18 20:36, Jan Kaliszewski wrote:
> Na szczęście Python sam stara się dowiedzieć, jakiego kodowania
> używa środowisko (terminal, wiersz poleceń bądź IDE czyli środowisko
> programistyczne takie jak SPE...) w którym został uruchomiony --
> informację tę można pobrać z sys.stdout.encoding
Fajnie by było, gdyby to było takie proste... sys.stdout.encoding
zawiera kodowanie tylko wtedy, kiedy stdout jest rzeczywiście
w użyciu. Jeśli wyjście jest przekierowane, zawiera None,
co spowoduje, że w tym skrypcie:
> # -*- coding: iso-8859-2 -*-
> import sys
> print "żółć".decode('iso-8859-2').encode(sys.stdout.encoding)
Wystąpi wyjątek TypeError: encode() argument 1 must be string, not None.
> Ale nie dość na tym. print jest na tyle mądre, że jeżeli podamy mu
> obiekt unicode, a nie str, zakoduje ten obiekt kodowaniem takim,
> jakie jest w sys.stdout.encoding
J.w., czyli tylko w przypadku braku przekierowania stdout.
Po przekierowaniu użyte będzie kodowanie domyślne, czyli to
zwracane przez sys.getdefaultencoding().
> Przy czym -- to osobna sprawa, ale warto ją zauważyć i stosować gdzie
> się da -- zamiast tworzyć obiekt str (z str-owego literału "żółć")
> i następnie go dekodować do postaci unicode za pomocą kodowania jakim
> kodowane są źródłą naszego programu -- możemy od razu utworzyć obiekt
> unicode (z unicodowego literału u"żółć"):
Popieram. :-)
> Oczywiście może się zdarzyć, że w sys.stdout.encoding znajdzie się
> kodowanie nie obsługujące podanych znaków --
Oczywiście...
> np. gdy standardowe wyjście
> przekierowano do pliku (sys.stdout.encoding zawiera wówczas kodowanie
> ascii)
ale przykład niedobry... sys.stdout.encoding zawiera wówczas None.
> Więc w programach, które nie są prostymi skryptami czy programikami
> do użytku własnego i znajomych, można dać np.:
>
> # -*- coding: iso-8859-2 -*-
> try:
> print u"żółć"
> except UnicodeEncodeError:
> print u"żółć".encode(errors=ignore)
> # ewentualnie: print u"żółć".encode('unicode_escape')
>
> lub nawet:
>
> # -*- coding: iso-8859-2 -*-
> import locale
> KODOWANIE_Z_LOCALE = locale.getpreferredencoding()
>
> try:
> print u"żółć"
> except UnicodeEncodeError:
> print u"żółć".encode(KODOWANIE_Z_LOCALE, errors=ignore)
>
Sam zwykle stosuję to drugie, ale pamiętając o tym, że np. w Windows
domyślnie kodowanie w okienku poleceń (cmd) i w samym systemie są
różne, co można łatwo sprawdzić wykonując skrypt:
#coding:utf-8
import locale, sys
print "preferred encoding is", locale.getpreferredencoding()
print "default encoding is", sys.getdefaultencoding()
print "stdout encoding is", sys.stdout.encoding
Bez przekierowania otrzymujemy np. taki wynik:
preferred encoding is cp1250
default encoding is ascii
stdout encoding is cp852
a z przekierowaniem taki:
preferred encoding is cp1250
default encoding is ascii
stdout encoding is None
Normalnie więc koduję zawartością sys.stdout.encoding, a jeśli
jest nieokreślona (None) używam albo locale.getpreferredencoding(),
albo jakiegoś z góry określonego (najczęściej UTF-8).
--
mrg
Technical Details
Message-ID:
<4c1c02fb$0$2585$65785112@news.neostrada.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.glorb.com!transit3.readnews.com!news-out.readnews.com!news-xxxfer.readnews.com!nx02.iad01.newshosting.com!newshosting.com!newsfeed.neostrada.pl!unt-exc-01.news.neostrada.pl!unt-spo-b-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mailReferences:
<hvb91g$rpp$1@node2.news.atman.pl> <op.veidzb06fvx12t@jerzozwiesz.localdomain>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.glorb.com!transit3.readnews.com!news-out.readnews.com!news-xxxfer.readnews.com!nx02.iad01.newshosting.com!newshosting.com!newsfeed.neostrada.pl!unt-exc-01.news.neostrada.pl!unt-spo-b-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail Date: Sat, 19 Jun 2010 01:36:27 +0200 From: marrgol <marspamrgol@gspammail.com> User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100317 x/3.0.4-2.2 Thunderbird/3.0.4 MIME-Version: 1.0 Newsgroups: pl.comp.lang.python Subject: Re: String, unicode, dziwny problem i 5 pytań - długie References: <hvb91g$rpp$1@node2.news.atman.pl> <op.veidzb06fvx12t@jerzozwiesz.localdomain> In-Reply-To: <op.veidzb06fvx12t@jerzozwiesz.localdomain> Lines: 96 Message-ID: <4c1c02fb$0$2585$65785112@news.neostrada.pl> Organization: Telekomunikacja Polska NNTP-Posting-Host: 80.54.82.172 X-Trace: 1276904187 unt-rea-a-02.news.neostrada.pl 2585 80.54.82.172:20471 X-Complaints-To: abuse@news.neostrada.pl Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit