Cómo verificar si la variable es una cadena con compatibilidad con Python 2 y 3

5 minutos de lectura

avatar de usuario
Caza de Randall

Soy consciente de que puedo usar: isinstance(x, str) en python-3.x pero también necesito verificar si algo es una cadena en python-2.x. Voluntad isinstance(x, str) funciona como se esperaba en python-2.x? ¿O tendré que verificar la versión y usar isinstance(x, basestr)?

Específicamente, en python-2.x:

>>>isinstance(u"test", str)
False

y python-3.x no tiene u"foo"

  • La sintaxis u”” para los literales Unicode se vuelve a introducir en Python 3.3

    – jfs

    2 de julio de 2012 a las 21:30

  • Extraño. Obtengo “` >>> isinstance(u”test”, basestring) True “` en Python 2.7.16

    – Darakian

    13 mayo 2019 a las 21:20


Si está escribiendo código compatible con 2.x y 3.x, probablemente querrá usar seis:

from six import string_types
isinstance(s, string_types)

  • Lo siento, estoy un poco confundido con el siguiente resultado. >>> isinstance(u"foo", string_types) True >>> isinstance(u"foo".encode("utf-8"), string_types) True Esperaba que isinstance(u”foo”, string_types) devolviera falso.

    – Chandler.Huang

    31 de marzo de 2016 a las 3:21


  • @Chandler.Huang esta pregunta se trata de identificar str y unicode en Python 2, o str en Python 3. Si no quieres unicode para contar con Python 2, solo usa str.

    – ecatmur

    31 de marzo de 2016 a las 8:42

  • @ecatmur woops, gracias! lo borré para que nadie se confunda

    – ejecutarDOSejecutar

    29/09/2017 a las 18:20

  • también puedes usarlo desde future paquete en lugar de six: from future.utils import string_types

    – Super Geo

    24 de junio de 2018 a las 19:36

El enfoque más conciso que he encontrado sin depender de paquetes como seis es:

try:
  basestring
except NameError:
  basestring = str

luego, suponiendo que haya estado buscando cadenas en Python 2 de la manera más genérica,

isinstance(s, basestring)

ahora también funcionará para Python 3+.

  • para py3, basestring = (str, bytes) de requests/compat.py

    – Tanky Woo

    17 de enero de 2016 a las 3:56


  • Bonito, pero ¿por qué? Sería bueno si Python3 fuera compatible con versiones anteriores aquí. Las soluciones anteriores funcionan. Sería incluso mejor, si no hubiera necesidad de ello.

    – Guettli

    4 de marzo de 2019 a las 19:37

  • Para satisfacer tanto el soporte de py2 &3 como el de mypy, terminé con if not hasattr(__builtins__, "basestring"): basestring = (str, bytes)

    – David Lee

    11 de abril de 2019 a las 3:33

¿Qué tal esto, funciona en todos los casos?

isinstance(x, ("".__class__, u"".__class__))

  • @holdenweb: No y sí, creo que es un truco ingenioso de “solo impactos donde sea necesario”.

    – Diletante

    31 de marzo de 2017 a las 19:10

  • La razón por la que me gusta esta respuesta es que es amigable con la migración de python2 a 3.

    – Tiagojdferreira

    18 de enero de 2018 a las 10:11

  • También opté por esta opción, envolviéndola en una función de ayuda, por lo que solo aparece una vez, y hay un lugar en la cadena de documentación para dar crédito a Fil.

    –Carl Smith

    21 de mayo de 2018 a las 12:27

  • Genial, y lo estaba usando yo mismo, hasta que me di cuenta de que también tengo from __future__ import unicode_literals activo. Ahora voy con: isinstance(val, (str, u"".__class__))

    –Graham Klyne

    23 de agosto de 2018 a las 15:33


avatar de usuario
steveha

Esta es la respuesta de @Lev Levitsky, reescrita un poco.

try:
    isinstance("", basestring)
    def isstr(s):
        return isinstance(s, basestring)
except NameError:
    def isstr(s):
        return isinstance(s, str)

los try/except La prueba se realiza una vez y luego define una función que siempre funciona y es lo más rápida posible.

EDITAR: En realidad, ni siquiera necesitamos llamar isinstance(); solo tenemos que evaluar basestring y a ver si conseguimos NameError:

try:
    basestring  # attempt to evaluate basestring
    def isstr(s):
        return isinstance(s, basestring)
except NameError:
    def isstr(s):
        return isinstance(s, str)

Creo que es más fácil seguir con la llamada a isinstance()aunque.

avatar de usuario
toto_tico

los future biblioteca agrega (a Python 2) nombres compatiblesasí que puedes continuar escribiendo Python 3. Puedes simplemente hacer lo siguiente:

from builtins import str
isinstance(x, str) 

para instalarlosolo ejecuta pip install future.

Como un advertenciasolo es compatible python>=2.6,>=3.3pero es más moderno que sixque es solo recomendado si se usa python 2.5

  • from builtins import str; isinstance('foo', str) devuelve Falso en python 2.7

    – emre

    11 de febrero de 2021 a las 0:59


  • Esto no funcionará con los literales de cadena de Python 2.

    – Aarón D.

    21 oct 2021 a las 14:56

avatar de usuario
lev levitsky

Tal vez use una solución alternativa como

def isstr(s):
    try:
        return isinstance(s, basestring)
    except NameError:
        return isinstance(s, str)

  • from builtins import str; isinstance('foo', str) devuelve Falso en python 2.7

    – emre

    11 de febrero de 2021 a las 0:59


  • Esto no funcionará con los literales de cadena de Python 2.

    – Aarón D.

    21 oct 2021 a las 14:56

Puede obtener la clase de un objeto llamando object.__class__entonces para verificar si el objeto es el tipo de cadena predeterminado:

    isinstance(object,"".__class__)

Y puede colocar lo siguiente en la parte superior de su código para que las cadenas entre comillas estén en Unicode en Python 2:

    from __future__ import unicode_literals

  • Yo esta solución un poco. Descubrí que puede ser útil definir str = “”.__class__, que ahora permite que isinstance(object, str) se escriba normalmente, y también garantiza que str(object) devolverá una cadena Unicode tanto en Python 2 como en Python 3.

    – amicitas

    5 de diciembre de 2013 a las 14:10

  • Esto no funciona al analizar XML: some_element.text es un ‘str’ pero la comparación con ‘unicode’ fallaría

    – bóveda

    24 de julio de 2015 a las 13:12

  • No funciona con cadenas Unicode en Python 2: isinstance(u’XXX’, ”.__class__) == Falso

    – Fil

    13 de noviembre de 2015 a las 18:41

¿Ha sido útil esta solución?