Quelles sont les différences entre type() et isinstance()?
  quelles sont les différences entre ces deux fragments de code?
En utilisant  type() :  
import types
if type(a) is types.DictType:
    do_something()
if type(b) in types.StringTypes:
    do_something_else()
  utilisant  isinstance() :  
if isinstance(a, dict):
    do_something()
if isinstance(b, str) or isinstance(b, unicode):
    do_something_else()
6 réponses
  Pour résumer le contenu d'autres (déjà bien!) réponses,  isinstance  s'adresse à l'héritage (une instance d'une classe dérivée    est une instance    d'une classe de base, aussi), alors que la vérification de l'égalité de  type  ne le fait pas (il exige l'identité des types et rejette les instances de sous-types, alias sous-classes).  
  normalement, en Python, vous voulez que votre code supporte l'héritage, bien sûr (puisque l'héritage est si pratique, il serait mauvais pour empêcher le code d'utiliser le vôtre de l'utiliser!), ainsi  isinstance est moins mauvais que le contrôle d'identité de type  s parce qu'il soutient parfaitement l'héritage.  
 ce n'est pas que isinstance est  bon  , pensez-vous-c'est juste  moins mauvais   que la vérification de l'égalité des types.  La solution normale, pythonique, préférée est presque invariablement "duck typing": essayez d'utiliser l'argument    comme si    il était d'un certain type désiré, le faire dans un try  /  except  déclaration attraper toutes les exceptions qui pourraient se poser si l'argument n'était pas en fait de ce type (ou tout autre type joliment canard imitant; -), et dans la clause  except , essayer quelque chose d'autre (en utilisant l'argument "comme si" il était d'un autre type).  
  basestring     est   , cependant, tout à fait un cas spécial-un type de bâtiment qui existe    seulement    pour vous permettre d'utiliser  isinstance   (à la fois  str  et  unicode  sous-classe  basestring  ). Les chaînes sont des séquences (on peut les indexer, les couper en boucle, etc.)...), mais vous voulez généralement les traiter comme des types" scalaires " -il est quelque peu incovenient (mais un cas d'utilisation assez fréquente) pour traiter toutes sortes de chaînes (et peut-être d'autres types scalaires, c.-à-d., ceux que vous ne pouvez pas boucler sur) une voie, tous les conteneurs (listes, ensembles, dicts, ...) d'une autre manière, et  basestring  plus  isinstance  vous aide à le faire-la structure globale de cet idiome est quelque chose comme:  
if isinstance(x, basestring)
  return treatasscalar(x)
try:
  return treatasiter(iter(x))
except TypeError:
  return treatasscalar(x)
 on pourrait dire que basestring est une  classe de Base abstraite  ("ABC")-il n'offre aucune fonctionnalité concrète aux sous-classes, mais existe plutôt comme un" marqueur", principalement pour une utilisation avec isinstance . Le concept est évidemment en croissance en Python, depuis    PEP 3119   , qui introduit une généralisation de celui-ci, a été accepté et a été mis en œuvre à partir de Python 2.6 et 3.0.  
 le PEP indique clairement que, bien que L'ABC puisse souvent remplacer le canard dactylographié, il n'y a généralement pas de grande pression pour le faire (voir  ici  ). Abc tel que mis en œuvre dans les dernières versions de Python n'offrent cependant des goodies supplémentaires:  isinstance  (et  issubclass  ) peut maintenant signifie plus que "[l'instance] une classe dérivée" (en particulier, toute classe peut être "enregistré" avec un ABC de sorte qu'il s'affiche comme une sous-classe, et ses instances les instances de L'ABC); et L'ABCs peut également offrir une commodité supplémentaire aux sous-classes réelles d'une manière très naturelle via des applications de modèle de conception de méthode de Template (voir    ici    et    ici    [[partie II]] pour plus de détails sur le DP TM, en général et spécifiquement en Python, indépendant de L'ABCs).  
pour la mécanique sous-jacente du support ABC tel qu'offert en python 2.6, voir ici ; pour leur version 3.1, très similaire, voir ici . Dans les deux versions, le module de bibliothèque standard collections (c'est la version 3.1-Pour la version 2.6 très similaire, voir ici ) offre plusieurs ABC utiles.
  pour les besoins de cette réponse, la chose clé à retenir à propos de L'ABC (au-delà d'un placement sans doute plus naturel pour la fonctionnalité TM DP, par rapport à L'alternative classique de python des classes de mixin telles que    UserDict.DictMixin   ) est qu'ils rendent isinstance (et issubclass ) beaucoup plus attrayant et envahissant (en python 2.6 et aller de l'avant) qu'ils ne l'étaient (en 2.5 et avant), et donc, par contraste, faire vérifier l'égalité de type une pratique encore pire dans les versions récentes de Python qu'il ne l'était déjà.  
  Voici pourquoi  isinstance est mieux que type :  
class Vehicle:
    pass
class Truck(Vehicle):
    pass
dans ce cas, un objet de camion est un véhicule, mais vous obtiendrez ceci:
isinstance(Vehicle(), Vehicle)  # returns True
type(Vehicle()) == Vehicle      # returns True
isinstance(Truck(), Vehicle)    # returns True
type(Truck()) == Vehicle        # returns False, and this probably won't be what you want.
 en d'autres termes, isinstance  vaut également pour les sous-classes.  
Voir aussi: comment comparer le type d'un objet en Python?
Différences entre les
isinstance()ettype()en Python?
contrôle de Type avec
isinstance(obj, Base)
permet des instances de sous-classes et plusieurs bases possibles:
isinstance(obj, (Base1, Base2))
alors que le contrôle de type porte sur
type(obj) is Base
supporte uniquement le type référencé.
  comme sidenote,   is  est probablement plus approprié que  
type(obj) == Base
parce que les classes sont des Singleton.
Eviter la vérification de type-use polymorphisme (duck-typing)
en Python, habituellement vous voulez autoriser n'importe quel type pour vos arguments, le traiter comme prévu, et si l'objet ne se comporte pas comme prévu, il soulèvera une erreur appropriée. Ceci est connu comme le polymorphisme, aussi connu comme duck-typing.
def function_of_duck(duck):
    duck.quack()
    duck.swim()
Si le code ci-dessus fonctionne, nous pouvons présumer notre argument est un canard. Ainsi nous pouvons passer dans d'autres choses sont des sous-types réels de canard:
function_of_duck(mallard)
ou qui travaillent comme un canard:
function_of_duck(object_that_quacks_and_swims_like_a_duck)
et notre code fonctionne toujours.
toutefois, dans certains cas, il est souhaitable de procéder à un contrôle de type explicite. Peut-être avez-vous des choses sensées à faire avec différents types d'objets. Par exemple, L'objet Pandas Dataframe peut être construit à partir de dicts ou . Dans un tel cas, votre code doit savoir quel type d'argument c'est l'obtention de sorte qu'il peut gérer correctement.
donc, pour répondre à la question:
  différences entre  isinstance()  et  type()  en Python?  
  
  Permettez-moi de démontrer la différence:
  type   
  
  dites que vous devez vous assurer un certain comportement si votre fonction est un certain genre d'argument (un cas d'utilisation pour les constructeurs). Si vous vérifiez pour le type comme ceci:
def foo(data):
    '''accepts a dict to construct something, string support in future'''
    if type(data) is not dict:
        # we're only going to test for dicts for now
        raise ValueError('only dicts are supported for now')
 si nous essayons de passer dans un dict qui est une sous-classe de dict (comme nous devrions pouvoir, si nous nous attendons à ce que notre code suive le principe de  Liskov Substitution  , que les sous-types peuvent être substitués pour les types) notre code casse!:  
from collections import OrderedDict
foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))
soulève une erreur!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
ValueError: argument must be a dict
   isinstance   
  
    mais si nous utilisons  isinstance , nous pouvons soutenir Liskov Substitution!:  
def foo(a_dict):
    if not isinstance(a_dict, dict):
        raise ValueError('argument must be a dict')
    return a_dict
foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))
  renvoie  OrderedDict([('foo', 'bar'), ('fizz', 'buzz')])   
Classes De Base Abstraites
  En fait, nous pouvons faire encore mieux.   collections  fournit des Classes de Base abstraites qui appliquent des protocoles minimaux pour divers types. Dans notre cas, si nous attendons seulement le protocole  Mapping  , nous pouvons faire ce qui suit, et notre code devient encore plus flexible:  
from collections import Mapping
def foo(a_dict):
    if not isinstance(a_dict, Mapping):
        raise ValueError('argument must be a dict')
    return a_dict
réponse au commentaire:
il convient de noter que le type peut être utilisé pour vérifier la compatibilité avec plusieurs classes en utilisant
type(obj) in (A, B, C)
Oui, vous pouvez tester l'égalité des types, mais au lieu de ce qui précède, utilisez les bases multiples pour le flux de contrôle, à moins que vous n'autorisiez spécifiquement que ces types:
isinstance(obj, (A, B, C))
 la différence, encore une fois, est que isinstance  supporte des sous-classes qui peuvent être substituées au parent sans briser le programme, une propriété connue sous le nom de substitution de Liskov.   
encore mieux, cependant, inversez vos dépendances et ne Vérifiez pas du tout les types spécifiques.
Conclusion
  donc, puisque nous voulons soutenir des sous-classes de substitution, dans la plupart des cas, nous voulons éviter vérification de type avec  type et préférez vérification de type avec isinstance  -à moins que vous ayez vraiment besoin de connaître la classe précise d'une instance.   
  cette dernière solution est préférable, car elle permet de traiter correctement les sous-classes. En fait, votre exemple peut être écrit encore plus facilement parce que le second paramètre de isinstance() peut être un tuple: 
if isinstance(b, (str, unicode)):
    do_something_else()
  ou, à l'aide de la  basestring  classe abstraite:  
if isinstance(b, basestring):
    do_something_else()
selon la documentation de python voici une déclaration:
8.15. types-noms pour les types intégrés
à partir de Python 2.2, intégré fonctions d'usine telles que
int()etstr()sont également des noms pour le types correspondants.
  Donc     isinstance()     doit être préféré à     type()     .   
 pour les différences réelles, nous pouvons le trouver dans code , mais je ne peux pas trouver l'implémentation du comportement par défaut du isinstance() .   
Toutefois, nous pouvons obtenir un semblable abc.__instancecheck__ selon __instancecheck__ .
  au-dessus de  abc.__instancecheck__ , après avoir utilisé l'essai ci-dessous:  
# file tree
# /test/__init__.py
# /test/aaa/__init__.py
# /test/aaa/aa.py
class b():
pass
# /test/aaa/a.py
import sys
sys.path.append('/test')
from aaa.aa import b
from aa import b as c
d = b()
print(b, c, d.__class__)
for i in [b, c, object]:
    print(i, '__subclasses__',  i.__subclasses__())
    print(i, '__mro__', i.__mro__)
    print(i, '__subclasshook__', i.__subclasshook__(d.__class__))
    print(i, '__subclasshook__', i.__subclasshook__(type(d)))
print(isinstance(d, b))
print(isinstance(d, c))
<class 'aaa.aa.b'> <class 'aa.b'> <class 'aaa.aa.b'>
<class 'aaa.aa.b'> __subclasses__ []
<class 'aaa.aa.b'> __mro__ (<class 'aaa.aa.b'>, <class 'object'>)
<class 'aaa.aa.b'> __subclasshook__ NotImplemented
<class 'aaa.aa.b'> __subclasshook__ NotImplemented
<class 'aa.b'> __subclasses__ []
<class 'aa.b'> __mro__ (<class 'aa.b'>, <class 'object'>)
<class 'aa.b'> __subclasshook__ NotImplemented
<class 'aa.b'> __subclasshook__ NotImplemented
<class 'object'> __subclasses__ [..., <class 'aaa.aa.b'>, <class 'aa.b'>]
<class 'object'> __mro__ (<class 'object'>,)
<class 'object'> __subclasshook__ NotImplemented
<class 'object'> __subclasshook__ NotImplemented
True
False
  j'obtiens cette conclusion,
Au lieu de  type  :  
# according to `abc.__instancecheck__`, they are maybe different! I have not found negative one 
type(INSTANCE) ~= INSTANCE.__class__
type(CLASS) ~= CLASS.__class__
  pour  isinstance :  
# guess from `abc.__instancecheck__`
return any(c in cls.__mro__ or c in cls.__subclasses__ or cls.__subclasshook__(c) for c in {INSTANCE.__class__, type(INSTANCE)})
  BTW: mieux de ne pas mélanger les utiliser  relative and absolutely import  , utilisez  absolutely import  de project_dir( ajouté par  sys.path  )