web-dev-qa-db-fra.com

Comment comparer le type d'un objet en Python?

En gros, je veux faire ceci:

obj = 'str'
type ( obj ) == string

J'ai essayé:

type ( obj ) == type ( string )

et ça n'a pas marché.

Aussi, qu'en est-il des autres types? Par exemple, je ne pouvais pas répliquer NoneType.

149
Joan Venge
isinstance()

Dans votre cas, isinstance("this is a string", str) retournera True.

Vous voudrez peut-être aussi lire ceci: http://www.canonical.org/~kragen/isinstance/

218
anthony

isinstance fonctionne:

if isinstance(obj, MyClass): do_foo(obj)

mais, gardez à l’esprit: si cela ressemble à un canard et si cela ressemble à un canard, c’est un canard.

EDIT: Pour le type None, vous pouvez simplement faire:

if obj is None: obj = MyClass()
35
fengshaun

Premièrement, évitez toutes les comparaisons de types. Ils sont très, très rarement nécessaires. Parfois, ils aident à vérifier les types de paramètres dans une fonction - même si c'est rare. Des données de type incorrect vont générer une exception, et c'est tout ce dont vous aurez besoin.

Toutes les fonctions de conversion de base correspondront à la fonction type.

type(9) is int
type(2.5) is float
type('x') is str
type(u'x') is unicode
type(2+3j) is complex

Il y a quelques autres cas.

isinstance( 'x', basestring )
isinstance( u'u', basestring )
isinstance( 9, int )
isinstance( 2.5, float )
isinstance( (2+3j), complex )

Aucun, BTW, n’a jamais besoin de ce type de vérification de type. None est la seule instance de NoneType. L'objet None est un Singleton. Il suffit de vérifier pour aucun

variable is None

BTW, ne pas utiliser ce qui précède en général. Utilisez des exceptions ordinaires et le polymorphisme naturel de Python.

32
S.Lott

Pour les autres types, consultez le module types :

>>> import types
>>> x = "mystring"
>>> isinstance(x, types.StringType)
True
>>> x = 5
>>> isinstance(x, types.IntType)
True
>>> x = None
>>> isinstance(x, types.NoneType)
True

P.S. Dactylographier est une mauvaise idée.

23
Paolo Bergantino

Vous pouvez toujours utiliser l'astuce type(x) == type(y), où y est un type de type connu.

# check if x is a regular string
type(x) == type('')
# check if x is an integer
type(x) == type(1)
# check if x is a NoneType
type(x) == type(None)

Il y a souvent de meilleures façons de le faire, en particulier avec les pythons récents. Mais si vous ne voulez vous souvenir que d’une chose, vous pouvez vous en rappeler.

Dans ce cas, les meilleurs moyens seraient:

# check if x is a regular string
type(x) == str
# check if x is either a regular string or a unicode string
type(x) in [str, unicode]
# alternatively:
isinstance(x, basestring)
# check if x is an integer
type(x) == int
# check if x is a NoneType
x is None

Notez le dernier cas: il n'y a qu'une seule instance de NoneType en python, et il s'agit de None. Vous verrez beaucoup de NonType dans les exceptions (TypeError: 'NoneType' object is unsubscriptable - m'arrive tout le temps ..), mais vous n'aurez presque jamais besoin de s'y référer dans le code.

Enfin, comme le souligne fengshaun, la vérification de type dans python n’est pas toujours une bonne idée. Il est plus simple d'utiliser Pythonic comme si c'était le type attendu et d'attraper (ou d'autoriser la propagation) les exceptions qui en résultent.

14
John Fouhy

Tu es très proche! string est un module, pas un type. Vous voudrez probablement comparer le type de obj à l'objet type pour les chaînes, à savoir str:

type(obj) == str  # this works because str is already a type

Alternativement:

type(obj) == type('')

Notez que dans Python 2, si obj est un type Unicode, aucun des éléments ci-dessus ne fonctionnera. Pas plus que isinstance(). Voir les commentaires de John sur ce post pour savoir comment résoudre ce problème ... J'essaie de m'en souvenir depuis environ 10 minutes maintenant, mais j'avais un blocage de mémoire!

6
Jarret Hardie

C'est parce que tu dois écrire

s="hello"
type(s) == type("")

type accepte une instance et retourne son type. Dans ce cas, vous devez comparer les types de deux instances.

Si vous devez effectuer une vérification préventive, il est préférable de vérifier le type d’interface prise en charge.

Le type ne vous dit pas grand-chose, mis à part le fait que votre code souhaite une instance d'un type spécifique, indépendamment du fait que vous pourriez avoir une autre instance d'un type complètement différent qui conviendrait parfaitement car il implémente la même interface. .

Par exemple, supposons que vous ayez ce code

def firstElement(parameter):
    return parameter[0]

Supposons maintenant que vous disiez: je veux que ce code accepte uniquement un tuple.

import types

def firstElement(parameter):
    if type(parameter) != types.TupleType:
         raise TypeError("function accepts only a Tuple")
    return parameter[0]

Cela réduit la réutilisabilité de cette routine. Cela ne fonctionnera pas si vous passez une liste, une chaîne ou un numpy.array. Quelque chose de mieux serait

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    return parameter[0]

mais cela ne sert à rien: le paramètre [0] lève une exception si le protocole n'est pas satisfait de toute façon ... ceci à moins que vous ne vouliez éviter les effets secondaires ou que vous ayez à récupérer d'appels que vous puissiez appeler avant d'échouer. (Stupide) exemple, juste pour faire le point:

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    os.system("rm file")
    return parameter[0]

dans ce cas, votre code générera une exception avant d'exécuter l'appel system (). Sans vérification de l'interface, vous auriez supprimé le fichier, puis déclenché l'exception.

5
Stefano Borini

Utilisez str au lieu de string

type ( obj ) == str

Explication

>>> a = "Hello"
>>> type(a)==str
True
>>> type(a)
<type 'str'>
>>>
4
Neil

J'utilise type(x) == type(y)

Par exemple, si je veux vérifier quelque chose est un tableau:

type( x ) == type( [] )

vérification de chaîne:

type( x ) == type( '' ) or type( x ) == type( u'' )

Si vous voulez vérifier avec None, utilisez is

x is None
4
hasen

je pense que cela devrait le faire

if isinstance(obj, str)
2
Aziz

Le type ne fonctionne pas sur certaines classes. Si vous n'êtes pas sûr du type de l'objet, utilisez la méthode __class__, comme suit:

>>>obj = 'a string'
>>>obj.__class__ == str
True

Voir également cet article - http://www.siafoo.net/article/56

2
Toby Fernsler

Utilisez isinstance(object, type). Comme ci-dessus, il est facile à utiliser si vous connaissez la bonne type, par exemple,

isinstance('dog', str) ## gives bool True

Mais pour des objets plus ésotériques, cela peut être difficile à utiliser. Par exemple:

import numpy as np 
a = np.array([1,2,3]) 
isinstance(a,np.array) ## breaks

mais vous pouvez faire cette astuce:

y = type(np.array([1]))
isinstance(a,y) ## gives bool True 

Je recommande donc d'instancier une variable (y dans ce cas) avec un type d'objet à vérifier (par exemple, type(np.array())), puis d'utiliser isinstance.

1
travelingbones

Pour obtenir le type, utilisez le membre __class__, comme dans unknown_thing.__class__

Parler de frappe de canard est inutile ici car cela ne répond pas parfaitement à une bonne question. Dans mon code d'application, je n'ai jamais besoin de connaître le type de quelque chose, mais il est toujours utile d'avoir un moyen d'apprendre le type d'un objet. Parfois, il me faut la classe pour valider un test unitaire. La frappe de canard est un problème car tous les objets possibles ont la même API, mais un seul est correct. De plus, parfois, je gère le code de quelqu'un d'autre et je n'ai aucune idée du type d'objet qui m'a été transmis. C'est mon plus gros problème avec les langages à typage dynamique comme Python. La version 1 est très facile et rapide à développer. La version 2 est pénible, surtout si vous n'avez pas écrit la version 1. Donc, parfois, lorsque je travaille avec une fonction que je n'ai pas écrite, j'ai besoin de connaître le type d'un paramètre, juste pour que je sache quelles méthodes je peux faire appel à elle.

C'est là que le paramètre __class__ est utile. Autant que je sache, c’est le meilleur moyen (peut-être le seul) d’obtenir le type d’un objet.

1
MiguelMunoz

Vous pouvez comparer les classes pour le niveau de contrôle.

#!/usr/bin/env python
#coding:utf8

class A(object):
    def t(self):
        print 'A'
    def r(self):
        print 'rA',
        self.t()

class B(A):
    def t(self):
        print 'B'

class C(A):
    def t(self):
        print 'C'

class D(B, C):
    def t(self):
        print 'D',
        super(D, self).t()

class E(C, B):
    pass

d = D()
d.t()
d.r()

e = E()
e.t()
e.r()

print isinstance(e, D) # False
print isinstance(e, E) # True
print isinstance(e, C) # True
print isinstance(e, B) # True
print isinstance(e, (A,)) # True
print e.__class__ >= A, #False
print e.__class__ <= C, #False
print e.__class__ <  E, #False
print e.__class__ <= E  #True
0
quickes