1475 votes

Quelles sont les différences entre type() et isinstance() ?

Quelles sont les différences entre ces deux fragments de code ?

Utilisation de type() :

import types

if type(a) is types.DictType:
    do_something()
if type(b) in types.StringTypes:
    do_something_else()

Utilisation de isinstance() :

if isinstance(a, dict):
    do_something()
if isinstance(b, str) or isinstance(b, unicode):
    do_something_else()

2 votes

Note : Si ce n'est pas str et unicode (où vous pouvez simplement vérifier basestring ), vous pouvez utiliser un tuple pour vérifier plusieurs types. Pour vérifier si something est int ou str utiliser isinstance(something, (int, str)) .

1 votes

type() retourne le type de l'objet que vous avez mis en argument, et n'est généralement pas utile à moins d'être comparé à un type réel (tel que type(9) == int ). isinstance() renvoie un booléen - vrai ou faux - selon que l'objet est du type donné. isinstance est généralement plus élégant à utiliser plutôt que d'écrire une vérification d'égalité encombrante, dans la plupart des cas.

15voto

Xinus Points 7693

Selon la documentation python, voici une déclaration :

8.15. types - Noms pour les types intégrés

À partir de Python 2.2, les fonctions d'usine intégrées, comme les intégrées, telles que int() et str() sont également des noms pour les types correspondants.

Alors isinstance() doit être préféré à type() .

1voto

Cheney Points 729

Pour les différences réelles, nous pouvons les trouver dans code mais je n'arrive pas à trouver l'implémentation du comportement par défaut de l'interface utilisateur. isinstance() .

Cependant, nous pouvons obtenir un résultat similaire abc.__instancecheck__ en fonction de __instancecheck__ .

Du haut de la page abc.__instancecheck__ après avoir utilisé le test 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'en arrive à cette conclusion, Pour 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 vaut ne pas mélanger l'utilisation relative and absolutely import utiliser absolutely import de project_dir( ajouté par sys.path )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X