Diferencia entre revisiones de «Usuario:Lmorillas/intropyaytozgz/unicode»
De WikiEducator
(8 revisiones intermedias por el mismo usuario no mostrado) | |||
Línea 2: | Línea 2: | ||
− | {{Conocimiento previo| | + | {{Conocimiento previo|TOCdepth=2| |
Una cadena Unicode es una secuencia de '''code points''', que son números de 0 a 0x10ffff. Esta secuencia se tiene que representar en un conjunto de bytes (valores de 0 a 255) en memoria. Las reglas para traducir una cadena Unicode a una secuencia de bytes se llama '''encoding'''. | Una cadena Unicode es una secuencia de '''code points''', que son números de 0 a 0x10ffff. Esta secuencia se tiene que representar en un conjunto de bytes (valores de 0 a 255) en memoria. Las reglas para traducir una cadena Unicode a una secuencia de bytes se llama '''encoding'''. | ||
}} | }} | ||
− | + | {{Objetivos|Title=El problema|TOCdepth=2| | |
− | {{ | + | |
'''¿Qué significa esto?''' | '''¿Qué significa esto?''' | ||
UnicodeDecodeError: 'ascii' codec | UnicodeDecodeError: 'ascii' codec | ||
can't decode byte 0xc4 in position | can't decode byte 0xc4 in position | ||
10: ordinal not in range(128) | 10: ordinal not in range(128) | ||
+ | |||
+ | <source lang="python"> | ||
+ | >>> f = open('aragon.txt') | ||
+ | >>> aragon_utf8 = f.read() | ||
+ | >>> aragon_utf8 | ||
+ | 'Arag\xc3\xb3n' | ||
+ | >>> len(aragon_utf8) | ||
+ | 7 | ||
+ | >>>type(aragon_utf8) | ||
+ | <type 'str'> | ||
+ | >>> unicode(aragon_utf8) | ||
+ | UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: | ||
+ | ordinal not in range(128) | ||
+ | |||
+ | # el problema: | ||
+ | >>> sys.getdefaultencoding() | ||
+ | 'ascii' | ||
+ | |||
+ | >>> aragon_uni = aragon_utf8.decode('utf-8') | ||
+ | >>> aragon_uni | ||
+ | u'Arag\xf3n' | ||
+ | >>> len(aragon_uni) | ||
+ | 6 | ||
+ | </source> | ||
}} | }} | ||
+ | {{Objetivos|Title=Conversión y codificación|TOCdepth=2| | ||
+ | <source lang="python"> | ||
+ | s.decode(encoding) | ||
+ | # <type 'str'> to <type 'unicode'> | ||
+ | >>> 'caña'.decode() | ||
+ | Traceback (most recent call last): | ||
+ | File "<stdin>", line 1, in <module> | ||
+ | UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128) | ||
+ | >>> 'caña'.decode(errors='ignore') | ||
+ | u'caa' | ||
+ | >>> 'caña'.decode(errors='replace') | ||
+ | u'ca\ufffd\ufffda' | ||
+ | >>> 'caña'.decode('utf-8') | ||
+ | u'ca\xf1a' | ||
+ | u.encode(encoding) | ||
+ | # <type 'unicode'> to <type 'str'> | ||
+ | >>> u'caña'.encode('ascii', 'ignore') | ||
+ | 'caa' | ||
+ | >>> u'caña'.encode('ascii', 'replace') | ||
+ | 'ca?a' | ||
+ | >>> u'caña'.encode('ascii') | ||
+ | Traceback (most recent call last): | ||
+ | File "<stdin>", line 1, in <module> | ||
+ | UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 2: ordinal not in range(128) | ||
+ | >>> u'caña'.encode('utf-8') | ||
+ | 'ca\xc3\xb1a' | ||
+ | </source> | ||
+ | }} | ||
− | {{Objetivo|Title=Normalizar cadena| | + | {{Objetivo|Title=Normalizar cadena|TOCdepth=2| |
<source lang="python"> | <source lang="python"> | ||
import unicodedata | import unicodedata | ||
− | def | + | def textoplano(s): |
− | + | def normalize(c): | |
− | + | return unicodedata.normalize("NFD", c)[0] # NFD: Normal Form Decomposition | |
return ''.join(normalize(c) for c in s) | return ''.join(normalize(c) for c in s) | ||
− | >>> | + | >>> textoplano('una cigüeña hábil') |
"una ciguena habil" | "una ciguena habil" | ||
</source> | </source> | ||
+ | }} | ||
+ | |||
+ | {{Objetivos|Title=Ficheros con codecs|TOCdepth=2| | ||
+ | |||
+ | <source lang="python"> | ||
+ | import codecs | ||
+ | |||
+ | # open(filename, mode='rb', encoding=None, errors='strict', buffering=1) | ||
+ | |||
+ | f = codecs.open('archivo', encoding='utf-8') | ||
+ | for linea in f: | ||
+ | print linea | ||
+ | </source> | ||
+ | |||
+ | <source lang="python"> | ||
+ | import codecs | ||
+ | |||
+ | >>> enc, dec, read_wrap, write_wrap = codecs.lookup('utf-8') | ||
+ | >>> f = open('utf8test.xml', 'wb') | ||
+ | >>> f = write_wrap(f) | ||
+ | >>> dec('caña') | ||
+ | (u'ca\xf1a', 5) | ||
+ | >>> enc(u'caña') | ||
+ | ('ca\xc3\xb1a', 4) | ||
+ | </source> | ||
+ | }} | ||
+ | |||
+ | {{Objetivos|Title=Recomendaciones|TOCdepth=2| | ||
+ | # Decodificar pronto (encoding --> unicode) | ||
+ | # Usar unicode siempre que sea posible | ||
+ | # Volver a codificar al final a un encoding | ||
}} | }} |
Última revisión de 19:03 3 dic 2012
Contenido
Conocimiento previo
Una cadena Unicode es una secuencia de code points, que son números de 0 a 0x10ffff. Esta secuencia se tiene que representar en un conjunto de bytes (valores de 0 a 255) en memoria. Las reglas para traducir una cadena Unicode a una secuencia de bytes se llama encoding.
|
El problema
¿Qué significa esto? UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 10: ordinal not in range(128) >>> f = open('aragon.txt') >>> aragon_utf8 = f.read() >>> aragon_utf8 'Arag\xc3\xb3n' >>> len(aragon_utf8) 7 >>>type(aragon_utf8) <type 'str'> >>> unicode(aragon_utf8) UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128) # el problema: >>> sys.getdefaultencoding() 'ascii' >>> aragon_uni = aragon_utf8.decode('utf-8') >>> aragon_uni u'Arag\xf3n' >>> len(aragon_uni) 6 |
Conversión y codificación
s.decode(encoding) # <type 'str'> to <type 'unicode'> >>> 'caña'.decode() Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128) >>> 'caña'.decode(errors='ignore') u'caa' >>> 'caña'.decode(errors='replace') u'ca\ufffd\ufffda' >>> 'caña'.decode('utf-8') u'ca\xf1a' u.encode(encoding) # <type 'unicode'> to <type 'str'> >>> u'caña'.encode('ascii', 'ignore') 'caa' >>> u'caña'.encode('ascii', 'replace') 'ca?a' >>> u'caña'.encode('ascii') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 2: ordinal not in range(128) >>> u'caña'.encode('utf-8') 'ca\xc3\xb1a' |
Normalizar cadena
import unicodedata def textoplano(s): def normalize(c): return unicodedata.normalize("NFD", c)[0] # NFD: Normal Form Decomposition return ''.join(normalize(c) for c in s) >>> textoplano('una cigüeña hábil') "una ciguena habil" |
Ficheros con codecs
import codecs # open(filename, mode='rb', encoding=None, errors='strict', buffering=1) f = codecs.open('archivo', encoding='utf-8') for linea in f: print linea import codecs >>> enc, dec, read_wrap, write_wrap = codecs.lookup('utf-8') >>> f = open('utf8test.xml', 'wb') >>> f = write_wrap(f) >>> dec('caña') (u'ca\xf1a', 5) >>> enc(u'caña') ('ca\xc3\xb1a', 4) |
Recomendaciones
|