Determina il tipo di un oggetto Python
Determina il tipo di un oggetto con type
>>> obj = object()
>>> type(obj)
<class 'object'>
Anche se funziona, evita i doppi attributi di sottolineatura come __class__
- non sono semanticamente pubblici e, anche se forse non in questo caso, le funzioni integrate di solito hanno un comportamento migliore.
>>> obj.__class__ # avoid this!
<class 'object'>
controllo del tipo
Esiste un modo semplice per determinare se una variabile è un elenco, un dizionario o qualcos'altro? Ricevo un oggetto che può essere di entrambi i tipi e devo essere in grado di dire la differenza.
Bene, questa è una domanda diversa, non usare il 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)
Questo riguarda il caso in cui l'utente potrebbe fare qualcosa di intelligente o sensato con la sottoclasse str
- secondo il principio di Sostituzione Liskov, si desidera poter utilizzare istanze di sottoclasse senza infrangere il codice - eisinstance
supporta.
Usa le astrazioni
Ancora meglio, potresti cercare una specifica classe base astratta da 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 semplicemente non controllare esplicitamente il tipo
O, forse meglio di tutto, usa la digitazione anatra e non controllare esplicitamente il codice. La tipizzazione anatra supporta la sostituzione di Liskov con più eleganza e meno verbosità.
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)
Conclusione
- Utilizzare
type
per ottenere effettivamente la classe di un'istanza.
- Utilizzare
isinstance
per verificare esplicitamente sottoclassi effettive o astrazioni registrate.
- E basta evitare il controllo del tipo dove ha senso.