2011-03-14 8 views
6

Dado en "cadena" arbitraria de una biblioteca que no tengo control, quiero asegurarme de que la "cadena" es un tipo Unicode y está codificada en utf-8. Me gustaría saber si esta es la mejor manera de hacer esto:¿Es esta la mejor manera de garantizar que una "cadena" unicode de python esté codificada en utf-8?

import types 

input = <some value from a lib I dont have control over> 

if isinstance(input, types.StringType): 
    input = input.decode("utf-8") 
elif isinstance(input, types.UnicodeType): 
    input = input.encode("utf-8").decode("utf-8") 

En mi código real envuelvo esto en un try/excepto y controlar los errores pero dejó esa parte.

Respuesta

5

Un objeto Unicode no está codificado (es interno pero esto debería ser transparente para usted como usuario de Python). La línea input.encode("utf-8").decode("utf-8") no tiene mucho sentido: obtienes la misma secuencia exacta de caracteres Unicode al final que tenías al principio.

if isinstance(input, str): 
    input = input.decode('utf-8') 

es todo lo que necesita para asegurarse de que los objetos str (cadenas de bytes) se convierten en cadenas Unicode.

+0

Estoy pasando esta cadena a otra lib que es una lib de C++ que necesita cadenas unicode codificadas en utf-8. ¿Es posible garantizar que la codificación del tipo Unicode sea UTF-8? – mcot

+1

¿La biblioteca C++ requiere interacción con la codificación interna del tipo Unicode de Python? Esto es dudoso y no creo que pueda cambiar trivialmente la codificación interna a UTF-8. Por otro lado, puede obtener un objeto str de Python, codificado en UTF-8: my_unicode_string.encode ('utf-8'). –

+0

¡Genial! Encontré tu respuesta después de 10 horas dolores de cabeza. –

2

Simply;

try: 
    input = unicode(input.encode('utf-8')) 
except ValueError: 
    pass 

Siempre es mejor pedir perdón que pedir permiso.

0

¿Estás seguro de que deseas una secuencia codificada en UTF-8 almacenada en un tipo Unicode? Normalmente, Python almacena caracteres en types.UnicodeType usando UCS-2 o -4, lo que a veces se denomina caracteres "anchos", que deberían ser capaces de contener caracteres de todos los scripts razonablemente comunes.

Uno se pregunta qué tipo de lib es que a veces produce tipos. StringType y a veces types.UnicodeType. Si me atrevería a adivinar, la lib siempre produce type.StringType, pero no dice en qué codificación está. Si ese es el caso, en realidad estás buscando un código que adivine qué juego de caracteres es un tipo.StringType está codificado como.

En la mayoría de los casos, esto es fácil, ya que puede suponer que está en, por ejemplo, latin-1 o UTF-8. Si el texto puede estar realmente en alguna codificación extraña (por ejemplo, correo entrante sin encabezado adecuado), necesita una lib que adivine la codificación. Ver http://chardet.feedparser.org/.

2

Creo que tiene un malentendido de Unicode y codificaciones. Los caracteres Unicode son solo números. Codificaciones son la representación de los números. Piensa en caracteres Unicode como un concepto como quince, y codificaciones como 15, 1111, F, XV. Debe conocer la codificación (decimal, binario, hexadecimal, números romanos) antes de poder decodificar una codificación y "conocer" el valor Unicode.

Si no tiene control sobre la cadena de entrada, es difícil convertirla en algo. Por ejemplo, si la entrada fue leída desde un archivo, usted debería saber la codificación del archivo de texto en decode de manera significativa en Unicode, y luego en encode en 'UTF-8' para su biblioteca C++.

Cuestiones relacionadas