variable tipos tipo str saber qué hace función español datos dato comprobar como python

str - tipos de datos en python pdf



Determinar el tipo de un objeto? (9)

Determine el tipo de un objeto Python

Determinar el tipo de un objeto con type

>>> obj = object() >>> type(obj) <class ''object''>

Aunque funciona, evite los atributos de subrayado doble como __class__ - no son semánticamente públicos y, aunque quizás no en este caso, las funciones integradas generalmente tienen un mejor comportamiento.

>>> obj.__class__ # avoid this! <class ''object''>

verificación de tipos

¿Hay una forma sencilla de determinar si una variable es una lista, un diccionario o algo más? Estoy recuperando un objeto que puede ser de cualquier tipo y necesito poder notar la diferencia.

Bueno, esa es una pregunta diferente, no uses tipo - usa isinstance :

def foo(obj): """given a string with items separated by spaces, or a list or tuple, do something sensible """ if isinstance(obj, str): obj = str.split() return _foo_handles_only_lists_or_tuples(obj)

Esto cubre el caso en el que su usuario podría estar haciendo algo inteligente o sensato mediante la subclasificación de str . De acuerdo con el principio de Sustitución de Liskov, usted quiere poder usar instancias de subclases sin romper su código, y la isinstance admite.

Utilizar abstracciones

Aún mejor, puede buscar una clase base abstracta abstracta de collections o numbers :

from collections import Iterable from numbers import Number def bar(obj): """does something sensible with an iterable of numbers, or just one number """ if isinstance(obj, Number): # make it a 1-tuple obj = (obj,) if not isinstance(obj, Iterable): raise TypeError(''obj must be either a number or iterable of numbers'') return _bar_sensible_with_iterable(obj)

O simplemente no hacer explícitamente la comprobación de tipo

O, quizás lo mejor de todo, utilice la tipificación de pato y no compruebe explícitamente su código. La tipificación del pato admite la sustitución de Liskov con más elegancia y menos verbosidad.

def baz(obj): """given an obj, a dict (or anything with an .items method) do something sensible with each key-value pair """ for key, value in obj.items(): _baz_something_sensible(key, value)

Conclusión

  • Utilice el type para obtener realmente la clase de una instancia.
  • Use isinstance para verificar explícitamente las subclases reales o las abstracciones registradas.
  • Y simplemente evite la comprobación de tipos donde tenga sentido.

¿Hay una forma sencilla de determinar si una variable es una lista, un diccionario o algo más? Estoy recuperando un objeto que puede ser de cualquier tipo y necesito poder notar la diferencia.


Además de las respuestas anteriores, vale la pena mencionar la existencia de collections.abc que contiene varias clases base abstractas (ABC) que complementan la tipificación de pato.

Por ejemplo, en lugar de verificar explícitamente si algo es una lista con:

isinstance(my_obj, list)

podría, si solo está interesado en ver si el objeto que tiene permite obtener artículos, utilice collections.abc.Sequence :

from collections.abc import Sequence isinstance(my_obj, Sequence)

Si está estrictamente interesado en los objetos que permiten obtener, configurar y eliminar elementos (es decir, secuencias mutables ), debería optar por collections.abc.MutableSequence .

Muchos otros ABC se definen allí, Mapping de objetos que se pueden usar como mapas, Iterable , Callable , etc. Se puede ver una lista completa de todo esto en la documentación de collections.abc .


En instancias de objeto también tiene el:

__class__

atributo. Aquí hay una muestra tomada de la consola Python 3.3.

>>> str = "str" >>> str.__class__ <class ''str''> >>> i = 2 >>> i.__class__ <class ''int''> >>> class Test(): ... pass ... >>> a = Test() >>> a.__class__ <class ''__main__.Test''>

Tenga en cuenta que en Python 3.xy clases New-Style (opcionalmente disponibles desde Python 2.6), la clase y el tipo se han fusionado y esto puede llevar a resultados inesperados. Principalmente por esta razón, mi forma favorita de probar tipos / clases es a la isinstance incorporada de isinstance .


Para obtener el tipo de un objeto, puede usar la función incorporada type() . Pasar un objeto como único parámetro devolverá el tipo de objeto de ese objeto:

>>> type([]) is list True >>> type({}) is dict True >>> type('''') is str True >>> type(0) is int True >>> type({}) <type ''dict''> >>> type([]) <type ''list''>

Por supuesto, esto también funciona para tipos personalizados:

>>> class Test1 (object): pass >>> class Test2 (Test1): pass >>> a = Test1() >>> b = Test2() >>> type(a) is Test1 True >>> type(b) is Test2 True

Tenga en cuenta que type() solo devolverá el tipo inmediato del objeto, pero no podrá informarle sobre la herencia de tipo.

>>> type(b) is Test1 False

Para cubrir eso, debes usar la función isinstance . Por supuesto, esto también funciona para los tipos incorporados:

>>> isinstance(b, Test1) True >>> isinstance(b, Test2) True >>> isinstance(a, Test1) True >>> isinstance(a, Test2) False >>> isinstance([], list) True >>> isinstance({}, dict) True

isinstance() suele ser la forma preferida de asegurar el tipo de un objeto porque también aceptará los tipos derivados. Entonces, a menos que realmente necesite el tipo de objeto (por cualquier razón), se isinstance() usar isinstance() sobre type() .

El segundo parámetro de isinstance() también acepta una tupla de tipos, por lo que es posible verificar varios tipos a la vez. isinstance luego devolverá true, si el objeto es de cualquiera de esos tipos:

>>> isinstance([], (tuple, list, set)) True


Podría ser más Pythonic usar un try ... except bloque. De esa manera, si tienes una clase que graba como una lista, o quacks como un dict, se comportará correctamente independientemente de cuál sea su tipo realmente .

Para aclarar, el método preferido para "decir la diferencia" entre los tipos de variables es con algo que se llama tipificación de pato : siempre que los métodos (y los tipos de retorno) a los que responde una variable sean lo que espera su subrutina, trátelo como lo espera. ser. Por ejemplo, si tiene una clase que sobrecarga a los operadores de corchetes con getattr y setattr , pero usa algún esquema interno divertido, sería apropiado que se comporte como un diccionario si eso es lo que está tratando de emular.

El otro problema con el type(A) is type(B) chequeo de type(A) is type(B) es que si A es una subclase de B , se evalúa como false cuando, programáticamente, desearía que fuera true . Si un objeto es una subclase de una lista, debería funcionar como una lista: la verificación del tipo como se presenta en la otra respuesta lo evitará. ( isinstance embargo, esta isinstance funcionará).


Puedes hacerlo usando type() :

>>> a = [] >>> type(a) <type ''list''> >>> f = () >>> type(f) <type ''tuple''>


Puedes usar type() o isinstance() .

>>> type([]) is list True

Tenga en cuenta que puede modificar la list o cualquier otro tipo asignando una variable en el alcance actual del mismo nombre.

>>> the_d = {} >>> t = lambda x: "aight" if type(x) is dict else "NOPE" >>> t(the_d) ''aight'' >>> dict = "dude." >>> t(the_d) ''NOPE''

Arriba vemos que el dict se reasigna a una cadena, por lo tanto, la prueba:

type({}) is dict

... falla

Para evitar esto y usar type() más cuidado:

>>> import __builtin__ >>> the_d = {} >>> type({}) is dict True >>> dict ="" >>> type({}) is dict False >>> type({}) is __builtin__.dict True


Si bien las preguntas son bastante antiguas, me topé con esto al mismo tiempo que descubrí una manera adecuada, y creo que todavía necesita aclaración, al menos para Python 2.x (no verifiqué Python 3, pero dado que el problema surge con las clases clásicas que se han ido en dicha versión, probablemente no importa).

Aquí estoy tratando de responder a la pregunta del título: ¿cómo puedo determinar el tipo de objeto arbitrario ? Otras sugerencias sobre el uso o no uso de la instancia están bien en muchos comentarios y respuestas, pero no estoy abordando esas preocupaciones.

El problema principal con el enfoque de type() es que no funciona correctamente con instancias de estilo antiguo :

class One: pass class Two: pass o = One() t = Two() o_type = type(o) t_type = type(t) print "Are o and t instances of the same class?", o_type is t_type

Ejecutar este fragmento generaría:

Are o and t instances of the same class? True

Lo cual, sostengo, no es lo que la mayoría de la gente esperaría.

El enfoque de __class__ es el más cercano a la corrección, pero no funcionará en un caso crucial: cuando el objeto pasado es una clase de estilo antiguo (¡no es una instancia!), Ya que esos objetos carecen de dicho atributo.

Este es el fragmento de código más pequeño que se me ocurre que satisface dicha pregunta legítima de manera consistente:

#!/usr/bin/env python from types import ClassType #we adopt the null object pattern in the (unlikely) case #that __class__ is None for some strange reason _NO_CLASS=object() def get_object_type(obj): obj_type = getattr(obj, "__class__", _NO_CLASS) if obj_type is not _NO_CLASS: return obj_type # AFAIK the only situation where this happens is an old-style class obj_type = type(obj) if obj_type is not ClassType: raise ValueError("Could not determine object ''{}'' type.".format(obj_type)) return obj_type


ten cuidado al usar isinstance

isinstance(True, bool) True >>> isinstance(True, int) True

pero escribe

type(True) == bool True >>> type(True) == int False