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.

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

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))

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

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.


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


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)

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

-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

types.ClassTypea été supprimé dans Python 3
Beau Barker
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.