Déterminer le type d'un objet Python
Déterminez le type d'un objet avec type
>>> obj = object()
>>> type(obj)
<class 'object'>
Bien que cela fonctionne, évitez les attributs de soulignement double comme __class__
- ils ne sont pas sémantiquement publics, et, même si ce n'est peut-être pas le cas dans ce cas, les fonctions intégrées ont généralement un meilleur comportement.
>>> obj.__class__ # avoid this!
<class 'object'>
vérification de type
Existe-t-il un moyen simple de déterminer si une variable est une liste, un dictionnaire ou autre chose? Je récupère un objet qui peut être de l'un ou de l'autre type et je dois pouvoir faire la différence.
Eh bien, c'est une question différente, n'utilisez pas de type - utilisez 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)
Cela couvre le cas où votre utilisateur pourrait faire quelque chose d'intelligent ou de sensible en sous str
- classant - selon le principe de la substitution de Liskov, vous voulez pouvoir utiliser des instances de sous-classe sans casser votre code - etisinstance
prend en charge cela.
Utiliser des abstractions
Encore mieux, vous pouvez rechercher une classe de base abstraite spécifique à partir de collections
ou 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)
Ou tout simplement ne pas vérifier explicitement le type
Ou, peut-être mieux encore, utilisez la frappe de canard et ne vérifiez pas explicitement votre code. Duck-typing soutient Liskov Substitution avec plus d'élégance et moins de 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)
Conclusion
- Utilisation
type
d'obtenir réellement la classe d'une instance.
- Utilisation
isinstance
de vérifier explicitement les sous-classes réelles ou les abstractions enregistrées.
- Et évitez simplement la vérification de type là où cela a du sens.