2011-11-04 8 views
9

Inizierò col dire che ho già visto questo post: Strange python print behavior with unicode, ma la soluzione offerta lì (usando PYTHONIOENCODING) non ha funzionato per me.python unicode che gestisce le differenze tra print e sys.stdout.write

Ecco il mio problema:

Python 2.6.5 (r265:79063, Apr 9 2010, 11:16:46) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2 
>>> a = u'\xa6' 
>>> print a 
¦ 

funziona bene, però:

>>> sys.stdout.write(a) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa6' in position 0: ordinal not in range(128) 

tiri un errore. Il post che ho collegato in alto suggerisce che questo è dovuto al fatto che la codifica della console predefinita è 'ascii'. Tuttavia, nel mio caso non lo è:

>>> sys.stdout.encoding 
'UTF-8' 

Quindi qualsiasi idea su cosa è al lavoro qui e su come risolvere questo problema?

Grazie D.

+1

On pitone 2.7 con la codifica del terminale utf-8, tutto sembra funzionare. Puoi provare sys.stdout.write (a.encode ("UTF-8")) e provare a vedere cosa succede? – yasar

+0

Sì, ha funzionato ... Oops, ho appena realizzato che ho usato la versione Python sbagliata per generare il campione. Avrei dovuto usare 2.6.5. Allora perché sta succedendo questo? Un bug in pre 2.7 Python? –

+0

Apparentemente, quando provi a scrivere su stdout, tu Python prova a codificare il tuo oggetto unicode con ascii, ma fallisce miseramente. Non sono sicuro del perché, ma il mio non lo fa :) – yasar

risposta

12

Ciò è dovuto ad una lunga bug che era fixed in python-2.7, ma troppo tardi per essere back-porting di python-2.6.

La documentazione indica che quando le stringhe Unicode vengono scritte su un file, devono essere convertite in stringhe di byte utilizzando file.encoding. Ma questo non veniva rispettato da sys.stdout, che invece utilizzava la codifica unicode predefinita. Questo è solitamente impostato su "ASCII" dal modulo site, ma può essere modificata con sys.setdefaultencoding:

Python 2.6.7 (r267:88850, Aug 14 2011, 12:32:40) [GCC 4.6.2] on linux3 
>>> a = u'\xa6\n' 
>>> sys.stdout.write(a) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec cant encode character u'\xa6' ... 
>>> reload(sys).setdefaultencoding('utf8') 
>>> sys.stdout.write(a) 
¦ 

Tuttavia, una soluzione migliore potrebbe essere quella di sostituire sys.stdout con un involucro:

class StdOut(object): 
    def write(self, string): 
     if isinstance(string, unicode): 
      string = string.encode(sys.__stdout__.encoding) 
     sys.__stdout__.write(string) 

>>> sys.stdout = StdOut() 
>>> sys.stdout.write(a) 
¦ 
+0

stdout ha molte funzioni diverse (chiudi, arrossisce, ...). Sarebbe meglio qui sostituire la sola funzione di scrittura – halflings