¿Cuál puede ser el mejor para verificar si var tiene str, unicode o None; pero nada mas?

Lo intenté con

if not isinstance(ads['number'], (str, unicode, None)):
    ....

Pero obtuve debajo de la excepción:

TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

`

0
Bhuro 28 feb. 2018 a las 10:07

4 respuestas

La mejor respuesta

Tiene la idea correcta, pero None no es una clase. Su tipo es NoneType, o alternativamente type(None). El último funciona de forma predeterminada en Python 2 y 3. El primero requiere una importación: from types import NoneType y solo funciona en Python 2.

2
Mad Physicist 28 feb. 2018 a las 07:24

Se puede utilizar

if not isinstance(a, (str, unicode, type(None))):
    ....

Y en python 2 (que parece estar usando) esto también funciona:

from types import NoneType
if not isinstance(a, (str, unicode, NoneType)):
    ....
3
hiro protagonist 28 feb. 2018 a las 07:23

Puede usar type para encontrar el método y verificarlo en una lista

Ej:

if type(None) in [str, unicode, type(None)]:
    print "ok"
1
Rakesh 28 feb. 2018 a las 07:13

En complemento a las otras respuestas (que son correctas), agregaría un comentario sobre la tipología de casos donde uno necesitaría tal prueba.

Distinguir entre una cadena y un tipo escalar

Si la pregunta es distinguir entre una cadena y un número, entonces pedir perdón en lugar de permiso funciona igual de bien:

a = 1
try:
    b = a.upper()
except AttributeError:
    ...

Dado que esa es la mentalidad de Python, a menudo simplifica las cosas, y también se ocupa del caso donde a es None . Si uno está tratando de evitar dicho error, entonces podría ser más fácil dejar que ocurra y luego detectarlo. También podría ser más confiable, porque también podría encargarse de casos en los que no se había pensado.

Distinguir entre una cadena y otros iterables

Sin embargo, un caso en el que no funcionará es cuando se quiere distinguir entre una cadena y una list (varias bibliotecas lo hacen con argumentos de función). El problema es que tanto una cadena como una lista son iterables, por lo que la cadena podría ejecutarse felizmente a través del código de la lista sin ningún error ... excepto que ahora tiene su cadena cortada en pedazos de un carácter.

>>> for el in a: print(el.upper())
...
H
E
L
L
O

(Y si el código falla, el error podría ser confuso). Para evitar ese efecto:

a = "hello"
if isinstance(a, str):
    ...
else:
    ...

En mi experiencia, es el único caso en el que es realmente recomendable usar una prueba con isinstance(x, (str,...)). Tengo curiosidad por saber si alguien conoce a otros?

1
fralau 28 feb. 2018 a las 07:49