python - open - ¿Cómo verifico si una cadena es unicode o ascii?
python open encoding utf-8 (10)
¿Qué tengo que hacer en Python para averiguar qué codificación?
En Python 3.x, todas las cadenas son secuencias de caracteres Unicode. y hacer la comprobación isinstance para str (que significa cadena de Unicode por defecto) debería ser suficiente.
isinstance(x, str)
Con respecto a python 2.x, la mayoría de las personas parece estar usando una instrucción if que tiene dos comprobaciones. uno para str y otro para unicode.
Si desea verificar si tiene un objeto ''similar a una cadena'' con una sola declaración, puede hacer lo siguiente:
isinstance(x, basestring)
Esto puede ayudar a alguien más, comencé a probar el tipo de cadena de la variable s, pero para mi aplicación, tenía más sentido simplemente devolver s como utf-8. El proceso que llama a return_utf, entonces sabe de qué se trata y puede manejar la cadena de manera apropiada. El código no es prístino, pero pretendo que sea independiente de la versión de Python sin una prueba de versión o la importación de seis. Por favor comente con mejoras al código de muestra a continuación para ayudar a otras personas.
def return_utf(s):
if isinstance(s, str):
return s.encode(''utf-8'')
if isinstance(s, (int, float, complex)):
return str(s).encode(''utf-8'')
try:
return s.encode(''utf-8'')
except TypeError:
try:
return str(s).encode(''utf-8'')
except AttributeError:
return s
except AttributeError:
return s
return s # assume it was already utf-8
Para compatibilidad con py2 / py3 simplemente use
import six if isinstance(obj, six.text_type)
Puede usar el Detector de codificación universal , pero tenga en cuenta que solo le dará la mejor respuesta, no la codificación real, porque es imposible saber la codificación de una cadena "abc", por ejemplo. Necesitará obtener información de codificación en otro lugar, por ejemplo, el protocolo HTTP usa el encabezado Content-Type para eso.
Si su código necesita ser compatible tanto con Python 2 como con Python 3, no puede usar directamente cosas como isinstance(s,bytes)
o isinstance(s,unicode)
sin envolverlos en try / except o una prueba de versión de python, porque los bytes
no están definidos en Python 2 y unicode
no está definido en Python 3.
Hay algunas soluciones feas. Una muy fea es comparar el nombre del tipo, en lugar de comparar el tipo en sí. Aquí hay un ejemplo:
# convert bytes (python 3) or unicode (python 2) to str
if str(type(s)) == "<class ''bytes''>":
# only possible in Python 3
s = s.decode(''ascii'') # or s = str(s)[2:-1]
elif str(type(s)) == "<type ''unicode''>":
# only possible in Python 2
s = str(s)
Una solución posiblemente menos fea es verificar el número de versión de Python, por ejemplo:
if sys.version_info >= (3,0,0):
# for Python 3
if isinstance(s, bytes):
s = s.decode(''ascii'') # or s = str(s)[2:-1]
else:
# for Python 2
if isinstance(s, unicode):
s = str(s)
Esos dos son antitónicos, y la mayoría de las veces probablemente hay una mejor manera.
Solo haz
type(s)
Uno dirá unicode
, el otro dirá str
.
Puede manejarlos por separado usando isinstance
, por ejemplo
if isinstance(s, str):
print ''s is a string object''
elif isinstance(s, unicode):
print ''s is a unicode object''
¿O quiere decir que tiene un str
y está tratando de averiguar si está codificado usando ASCII
o UTF-8
o algo más?
En ese caso, intente esto:
s.decode(''ascii'')
si genera una excepción, la cadena no es 100% ASCII.
Tenga en cuenta que en Python 3, no es justo decir nada de lo siguiente:
str
s son UTFx para cualquier x (por ejemplo, UTF8)str
s son unicodestr
s son colecciones ordenadas de personajes Unicode
El tipo str
de Python es (normalmente) una secuencia de puntos de código Unicode, algunos de los cuales se asignan a caracteres.
Incluso en Python 3, no es tan sencillo responder esta pregunta como te imaginas.
Una forma obvia de probar cadenas compatibles con ASCII es mediante un intento de codificación:
"Hello there!".encode("ascii")
#>>> b''Hello there!''
"Hello there... ☃!".encode("ascii")
#>>> Traceback (most recent call last):
#>>> File "", line 4, in <module>
#>>> UnicodeEncodeError: ''ascii'' codec can''t encode character ''/u2603'' in position 15: ordinal not in range(128)
El error distingue los casos.
En Python 3, incluso hay algunas cadenas que contienen puntos de código Unicode no válidos:
"Hello there!".encode("utf8")
#>>> b''Hello there!''
"/udcc3".encode("utf8")
#>>> Traceback (most recent call last):
#>>> File "", line 19, in <module>
#>>> UnicodeEncodeError: ''utf-8'' codec can''t encode character ''/udcc3'' in position 0: surrogates not allowed
Se utiliza el mismo método para distinguirlos.
Unicode no es una codificación, para citar a Kumar McMillan:
Si ASCII, UTF-8 y otras cadenas de bytes son "texto" ...
... entonces Unicode es "text-ness";
Es la forma abstracta del texto.
Lea el texto Unicode en Python de McMillan , completamente desmitificado de PyCon 2008, explica mucho mejor que la mayoría de las respuestas relacionadas en .
utilizar:
import six
if isinstance(obj, six. text_type)
dentro de seis bibliotecas se representa como:
if PY3:
string_types = str,
else:
string_types = basestring,
En Python 3, todas las cadenas son secuencias de caracteres Unicode. Hay un tipo de bytes
que contiene bytes en bruto.
En Python 2, una cadena puede ser de tipo str
o de tipo unicode
. Puedes decir que usando código algo como esto:
def whatisthis(s):
if isinstance(s, str):
print "ordinary string"
elif isinstance(s, unicode):
print "unicode string"
else:
print "not a string"
Esto no distingue "Unicode o ASCII"; sólo distingue los tipos de Python. Una cadena Unicode puede constar de puramente caracteres en el rango ASCII, y una derivación puede contener ASCII, Unicode codificado o incluso datos no textuales.