primero, solo uso Python 3.1 actualmente; su mérito central es tener cadenas de bytes desambiguadas de objetos Unicode. esto hace que la gran mayoría de las manipulaciones de texto sean mucho más seguras de lo que solían ser. Pesando en los billones de preguntas de los usuarios sobre los problemas de codificación de python 2.x, la convención u'äbc
de python 2.1 fue solo un error; con bytes
y bytearray
explícitos, la vida se vuelve mucho más fácil.
En segundo lugar, si py3k no es su sabor, intente ir con from __future__ import unicode_literals
, ya que esto imitará el comportamiento de py3k en Python 2.6 y 2.7. esto hubiera evitado el error (fácilmente cometido) que cometió al decir print 'exámple'.upper()
. esencialmente, esto es lo mismo que en py3k: print('exámple'.encode('utf-8').upper())
.comparar estas versiones (por py3k):
print('exámple'.encode('utf-8').upper())
print('exámple'.encode('utf-8').upper().decode('utf-8'))
print('exámple'.upper())
El primero de ellos es, básicamente, lo que hizo cuando utilizó una cadena pura 'exámple'
, siempre y cuando fija su codificación predeterminada a utf-8
(según un pronunciamiento BDFL, la configuración predeterminada la codificación en tiempo de ejecución es una mala idea, por lo que en py2 tendrás que engañar diciendo import sys; reload(sys); sys.setdefaultencoding('utf-8')
; presento una mejor solución para py3k a continuación). cuando se mira a la salida de estas tres líneas:
b'EX\xc3\xa1MPLE'
EXáMPLE
EXÁMPLE
se puede ver que cuando obtuve upper()
aplica al primer texto, actúa en bytes, no en caracteres. python permite el método upper()
en bytes, pero solo está definido en la interpretación de bytes de US-ASCII. ya que utf-8 utiliza los valores dentro de 8 bits pero fuera de de US-ASCII (128 hasta 255, que no son utilizados por US-ASCII), no se verán afectados por upper()
, por lo que cuando decodifiquemos nuevamente la segunda línea, obtenemos la minúscula á
. finalmente, la tercera línea lo hace bien, y sí, sorpresa, Python parece ser consciente de que Á
es la letra mayúscula correspondiente a á
. Hice una prueba rápida para ver qué caracteres Python 3 no convierte entre mayúsculas y minúsculas:
for cid in range(3000):
my_chr = chr(cid)
if my_chr == my_chr.upper() and my_chr == my_chr.lower():
say(my_chr)
hojeando la lista revela muy pocos casos de las letras latinas, cirílico, griego o; la mayor parte del resultado es caracteres y signos de puntuación no europeos. los únicos caracteres que pude encontrar que Python salió mal son Ԥ/ԥ (\ u0524, \ u0525, 'cirílico {capital | pequeño} letra pe con descendente'), siempre y cuando permanezcas fuera de los bloques Latin Extended-X (echa un vistazo a esos, podrían dar sorpresas), en realidad podrías usar ese método. por supuesto, no verifiqué la exactitud de las asignaciones.
por último, aquí es lo que he puesto en mi sección de arranque de aplicaciones py3k: un método que redefine la codificación sys.stdout
ve, con las referencias de caracteres numéricos (NCR) como de respaldo; esto tiene el efecto de que imprimir a la salida estándar nunca generará un error de codificación de Unicode. cuando trabajo en ubuntu, _sys.stdout.encoding
es utf-8
; cuando el mismo programa se ejecuta en Windows, podría ser algo pintoresco como cp850
. la salida puede parecer starnge, pero la aplicación se ejecuta sin generar una excepción en esos terminales poco claros.
#===========================================================================================================
# MAKE STDOUT BEHAVE IN A FAILSAFE MANNER
#-----------------------------------------------------------------------------------------------------------
def _harden_stdout():
"""Ensure that unprintable output to STDOUT does not cause encoding errors; use XML character references
so any kind of output gets a chance to render in a decipherable way."""
global _sys_TRM
_sys.stdout = _sys_TRM = _sys_io.TextIOWrapper(
_sys.stdout.buffer,
encoding = _sys.stdout.encoding,
errors = 'xmlcharrefreplace',
line_buffering = true)
#...........................................................................................................
_harden_stdout()
un consejo más: cuando se prueba, siempre trate de print repr(x)
o una cosa similar que revela la identidad de x
. todo tipo de malentendidos pueden surgir si solo print x
en py2 y x
es una cadena de octetos o un objeto Unicode. es muy desconcertante y propenso a causar muchos rasguños en la cabeza. como ya he dicho, intente mover al menos a py26 con el de un hechizo de literales unicode de importación futura.
y para cerrar, citando una cita: "Glifo Lefkowitz dice mejor en su artículo Encoding:
I believe that in the context of this discussion, the term "string" is meaningless. There is text, and there is byte-oriented data (which may very well represent text, but is not yet converted to it). In Python types, Text is unicode. Data is str. The idea of "non-Unicode text" is just a programming error waiting to happen."
actualización: acaba de encontrar pitón 3 convierte correctamente Latina de la LETRA DE LARGO S a S cuando uppercasing ordenada. !
py3k lo hace correctamente – SilentGhost