Comment vérifier si une variable est une classe ou non?

236

Je me demandais comment vérifier si une variable est une classe (pas une instance!) Ou non.

J'ai essayé d'utiliser la fonction isinstance(object, class_or_type_or_tuple)pour ce faire, mais je ne sais pas quel type aurait une classe.

Par exemple, dans le code suivant

class Foo: pass  
isinstance(Foo, **???**) # i want to make this return True.

J'ai essayé de remplacer " class" par ??? , mais j'ai réalisé que classc'est un mot-clé en python.

jeeyoungk
la source

Réponses:

335

Encore mieux: utilisez la inspect.isclassfonction.

>>> import inspect
>>> class X(object):
...     pass
... 
>>> inspect.isclass(X)
True

>>> x = X()
>>> isinstance(x, X)
True
>>> y = 25
>>> isinstance(y, X)
False
Benjamin Peterson
la source
7
Si vous souhaitez également inspect.isclassretourner Truesi l'objet à inspecter est une instance de classe , utilisezinspect.isclass(type(Myclass()))
michaelmeyer
8
Mieux que quoi :)?
Mad Physicist
8
@michaelmeyer type(whatever)renvoie toujours un objet qui est une classe, donc cette vérification est redondante. Si ce n'était pas le cas, il n'y aurait aucun moyen d'instancier whateveret vous ne pourriez donc pas effectuer la vérification en premier lieu.
a_guest
Ça ne marche pas pour moi. L'utilisation de python3 avec snakemake, type(snakemake.utils)retourne <class 'module'>et pourtant inspect.isclass(snakemake.utils)retourne False.
tedtoal
3
C'est parce snakemake.utilqu'un module n'est pas une classe?
Benjamin Peterson
44

Le inspect.isclass est probablement la meilleure solution, et il est vraiment facile de voir comment il est réellement mis en œuvre

def isclass(object):
    """Return true if the object is a class.

    Class objects provide these attributes:
        __doc__         documentation string
        __module__      name of module in which this class was defined"""
    return isinstance(object, (type, types.ClassType))
andrea_crotti
la source
5
rappelezimport types
nguyên
13
types.ClassTypen'est plus nécessaire dans Python 3 (et est supprimé).
kawing-chiu
cela ne fonctionne pas du tout avec les nouvelles classes de style .... même en python 2. n'utilisez pas cette solution seule
Erik Aronesty
Cela a été tiré du module d'inspection, donc je doute que cela ne fonctionne pas. C'est simple de vérifier avec Python2.7 par exempleIn [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
andrea_crotti
Il s'agit de l'implémentation Python 2, qui doit gérer les classes anciennes et nouvelles. Python 3 simplifie cela isinstance(object, type). Notez que des objets comme int, list, str, etc. sont aussi des cours, de sorte que vous ne pouvez pas l' utiliser pour établir une distinction entre les classes personnalisées définies en Python et intégrés dans les classes définies dans le code C .
Martijn Pieters
39
>>> class X(object):
...     pass
... 
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True
S.Lott
la source
1
Hm ... Belle réponse, mais quand je tape (Foo) sur ma classe Foo, il dit <type 'classobj'> au lieu de <type 'type'>. Je suppose que la différence vient du fait que X hérite de l'objet, mais Foo ne l'est pas. Y a-t-il une autre différence qui en découle? Merci.
jeeyoungk
6
Cela ne fonctionne pas pour les classes à l'ancienne:, 'class Old:pass' 'isinstance(Old, type) == False'mais inspect.isclass(Old) == True.
jfs
1
@jeeyoungk: Vous n'êtes pas "en supposant que la différence vient de ...", vous lisez en fait cela dans le code. Une sous-classe d'objet ("nouveau style") a les propriétés souhaitées, exactement ce que vous voyez ici.
S.Lott
12
Voici l'astuce - puisque cela fonctionne pour les classes de nouveau style, n'utilisez pas les classes de style ancien. Il est inutile d'utiliser des classes à l'ancienne.
S.Lott
isinstance (e, f) E est l'objet instancié, F est l'objet classe.
Dexter le
24
isinstance(X, type)

Renvoie Trueif Xis class et Falsesinon.

qnub
la source
3
J'obtiens False, même si X est une classe.
Mads Skjern
6
Cela ne fonctionne que pour les nouvelles classes de style. Les classes de style ancien sont de type 'classobj'. Donc, si vous utilisez d'anciennes classes de style, vous pouvez faire: importer des types isinstance (X, types.ClassType)
Charles L.
2
Cela semble être le même que S. Lott's answer, qui a quatre ans de plus.
Ethan Furman
5

Cette vérification est compatible avec Python 2.x et Python 3.x.

import six
isinstance(obj, six.class_types)

Il s'agit essentiellement d'une fonction wrapper qui effectue la même vérification que dans la réponse andrea_crotti.

Exemple:

>>> import datetime
>>> isinstance(datetime.date, six.class_types)
>>> True
>>> isinstance(datetime.date.min, six.class_types)
>>> False
Sergey
la source
1

la manière la plus simple est d'utiliser inspect.isclasscomme indiqué dans la réponse la plus votée.
les détails d'implémentation peuvent être trouvés sur python2 inspect et python3 inspect .
pour la classe new-style: isinstance(object, type)
pour la classe old-style: isinstance(object, types.ClassType)
em, pour la classe old-style, il utilise types.ClassType, voici le code de types.py :

class _C:
    def _m(self): pass
ClassType = type(_C)
lyu.l
la source
1

Benjamin Peterson a raison quant à l'utilisation de inspect.isclass()pour ce travail. Mais notez que vous pouvez tester si un Classobjet est un spécifique Class, et donc implicitement un Class, en utilisant la fonction intégrée issubclass . Selon votre cas d'utilisation, cela peut être plus pythonique.

from typing import Type, Any
def isclass(cl: Type[Any]):
    try:
        return issubclass(cl, cl)
    except TypeError:
        return False

Peut ensuite être utilisé comme ceci:

>>> class X():
...     pass
... 
>>> isclass(X)
True
>>> isclass(X())
False
masi
la source
-2

Il existe déjà quelques solutions de travail ici, mais en voici une autre:

>>> import types
>>> class Dummy: pass
>>> type(Dummy) is types.ClassType
True
Ztyx
la source
types.ClassTypea été supprimé dans Python 3
Beau Barker