Come verificare se una variabile è una classe o no?


236

Mi chiedevo come verificare se una variabile è una classe (non un'istanza!) Oppure no.

Ho provato a usare la funzione isinstance(object, class_or_type_or_tuple)per fare questo, ma non so che tipo avrebbe una classe.

Ad esempio, nel seguente codice

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

Ho provato a sostituire " class" con ??? , ma mi sono reso conto che classè una parola chiave in Python.

Risposte:


335

Ancora meglio: usa la inspect.isclassfunzione.

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

>>> x = X()
>>> isinstance(x, X)
True
>>> y = 25
>>> isinstance(y, X)
False

7
Se vuoi inspect.isclasstornare anche Truese l'oggetto da ispezionare è un'istanza di classe , usainspect.isclass(type(Myclass()))
michaelmeyer il

8
Meglio di cosa :)?
Fisico pazzo,

8
@michaelmeyer type(whatever)restituisce sempre un oggetto che è una classe, quindi questo controllo è ridondante. Altrimenti non ci sarebbe modo di creare un'istanza whatevere quindi non è possibile eseguire il controllo in primo luogo.
a_guest,

Non funziona per me. Utilizzando python3 con snakemake, type(snakemake.utils)ritorna <class 'module'>e tuttavia inspect.isclass(snakemake.utils)ritorna False.
mercoledì

3
Questo perché snakemake.utilun modulo non è una classe?
Benjamin Peterson,

44

Inspect.isclass è probabilmente la soluzione migliore ed è davvero facile vedere come è effettivamente implementato

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
ricordaimport types
nguyên

13
types.ClassTypenon è più necessario in Python 3 (e viene rimosso).
kawing-chiu

questo non funziona affatto con le nuove classi di stile .... anche in Python 2. Non usare questa soluzione da solo
Erik Aronesty,

È stato preso dal modulo inspect, quindi dubito che non funzioni. È semplice controllare con Python2.7 per esempioIn [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
andrea_crotti il

Questa è l'implementazione di Python 2, che deve gestire classi vecchio stile e nuovo stile. Python 3 semplifica questo isinstance(object, type). Si noti che oggetti come int, list, str, ecc, sono anche classi, quindi non è possibile utilizzare questo per distinguere tra classi personalizzate definite in Python e built-in classi definite nel codice C .
Martijn Pieters

39
>>> class X(object):
...     pass
... 
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True

1
Hm ... Bella risposta, ma quando scrivo (Foo) sulla mia classe Foo, dice <type 'classobj'> invece di <type 'type'>. Presumo che la differenza derivi dal fatto che X eredita dall'oggetto, ma Foo no. C'è qualche altra differenza derivante da questo? Grazie.
jeeyoungk,

6
Non funziona per le lezioni di vecchio stile:, 'class Old:pass' 'isinstance(Old, type) == False'ma inspect.isclass(Old) == True.
jfs,

1
@jeeyoungk: Non stai "supponendo che la differenza derivi da ...", in realtà lo stai leggendo nel codice. Una sottoclasse di oggetti ("nuovo stile") ha le proprietà desiderate, proprio quello che vedi qui.
S.Lott

12
Ecco il suggerimento: poiché questo funziona per le classi di nuovo stile, non usare classi di vecchio stile. Non ha senso usare classi vecchio stile.
S.Lott

isinstance (e, f) E è l'oggetto istanziato, F è l'oggetto di classe.
Dexter

24
isinstance(X, type)

Ritorno True se Xè classe e Falsese no.


3
Ottengo Falso, anche se X è una classe.
Mads Skjern,

6
Questo funziona solo per le nuove classi di stile. Le classi di vecchio stile sono di tipo "classobj". Quindi se stai usando classi di vecchio stile puoi fare: importare isinstance (X, types.ClassType)
Charles L.

2
Questo sembra essere lo stesso S. Lott's answer, che ha quattro anni in più.
Ethan Furman,

5

Questo controllo è compatibile con Python 2.xe Python 3.x.

import six
isinstance(obj, six.class_types)

Questa è sostanzialmente una funzione wrapper che esegue lo stesso controllo della risposta andrea_crotti.

Esempio:

>>> import datetime
>>> isinstance(datetime.date, six.class_types)
>>> True
>>> isinstance(datetime.date.min, six.class_types)
>>> False


1

il modo più semplice è quello di utilizzare inspect.isclasscome pubblicato nella risposta più votata.
i dettagli di implementazione possono essere trovati su python2 inspect e python3 inspect .
per la classe di nuovo stile: isinstance(object, type)
per la classe di vecchio stile: isinstance(object, types.ClassType)
em, per la classe di vecchio stile, sta usando types.ClassType, ecco il codice di types.py :

class _C:
    def _m(self): pass
ClassType = type(_C)

1

Benjamin Peterson ha ragione sull'uso di inspect.isclass()questo lavoro. Si noti tuttavia che è possibile verificare se un Classoggetto è uno specifico Class, e quindi implicitamente a Class, utilizzando la funzione integrata issubclass . A seconda del caso d'uso, questo può essere più pitonico.

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

Può quindi essere utilizzato in questo modo:

>>> class X():
...     pass
... 
>>> isclass(X)
True
>>> isclass(X())
False

-2

Ci sono già alcune soluzioni funzionanti qui, ma eccone un'altra:

>>> import types
>>> class Dummy: pass
>>> type(Dummy) is types.ClassType
True

types.ClassTypeè stato rimosso in Python 3
Beau Barker
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.