Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

¡Unicode en Python es Divertido!

>>> 'á'.decode('utf8')
u'\xe1'

Sin em­bar­go, hay una tram­pa. Te­nés que es­tar ab­so­lu­ta­men­te se­gu­ro que la co­sa que es­tás de­co­dean­do es un string de by­tes, y no un ob­je­to uni­co­de. Por­que los ob­je­tos uni­co­de tie­nen un mé­to­do de­co­de pe­ro es to­tal­men­te inú­ti­l, y su úni­co pro­pó­si­to en la vi­da es cau­sar es­te error pe­cu­lia­r:

>>> u'á'.decode('utf8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1'
in position 0: ordinal not in range(128)

¿Por­qué es pe­cu­lia­r? Por­que es un error de En­co­de. Cau­sa­do por lla­mar a de­co­de. Lo que pa­sa es que en los ob­je­tos uni­co­de, de­co­de, en la prác­ti­ca es al­go así:

def decode(self, encoding):
    return self.encode('ascii').decode(encoding)

El usua­rio quie­re un ob­je­to uni­co­de. Él tie­ne un ob­je­to uni­cde. Por de­fi­ni­ció­n, no exis­te un co­sa que sea "de­co­dear co­mo utf-8 un ob­je­to uni­co­de". No tie­ne sen­ti­do. Es co­mo pei­nar un pes­ca­do, o es­ca­lar una la­gu­na.

¡Lo que debería devolver es self! Además es suamente molesto que la única manera de evitar el error es chequear el tipo del objeto, lo que es activamente antipitónico.

Aún me­jo­r, no ten­ga­mos un mé­to­do de­co­de en ob­je­tos uni­co­de, que creo es la si­tua­ción en py­thon 3, pe­ro nun­ca lo va a ser en py­thon 2.

Así que aho­ra ya sa­be­n, y bue­na suer­te.

Juan B. Cabral / 2012-03-30 17:40:

supongo que no quiere devolver "self" por que decode tiene que devolver "OTRO" objeto unicode deberia devolver unicode(self)

Roberto Alsina / 2012-03-30 17:42:

Los objetos unicode son inmutables, así que no veo una diferencia práctica entre self y unicode(self)...

Juan B. Cabral / 2012-03-30 17:49:

practica inmediata seria que no rompa una validacion "is not" futura

Roberto Alsina / 2012-03-30 17:52:

Si estás validando strings usando "is" merecés que te falle :-)

Juan B. Cabral / 2012-04-11 23:38:

no pense en validar string con "is" pense en validar dos referencias al posible mismo objeto con "is" (osea pa lo que sirve is)

igual str hace lo mismo.... pero no me gusta

Joe / 2012-03-30 21:49:

No hay objetos unicode  en Python 3, solo str's (que tienen encode) y bytes (que tienen decode).

Roberto Alsina / 2012-03-30 21:54:

Si, los str en python 3 son unicode. Gracias por la aclaracion.

claudio canepa / 2012-03-31 01:24:

OT: para snippets chicos como los de hoy la zona del fin del code mas las siguientes lineas de texto normal no lucen del todo bien;

Si quisieras que la linea en blanco al final del .. code quedara fuera del block habria alguna manera sencilla de indicarlo en reST ?   

Roberto Alsina / 2012-03-31 01:43:

habría que revisar un cachito el CSS, debe ser un padding mal puesto nomas.


Contents © 2000-2021 Roberto Alsina