2012-03-03 10 views
10

Per determinare la classe, posso farlo:Come determinare il tipo di istanza di classe

class A: pass  
a = A 

type(A) is type #True 

o:

import inspect 
inspect.isclass(A) 

Ma come determinare il tipo di istanza di classe, non conoscendo il nome della classe?

Qualcosa di simile a questo:

isinstance(a, a.__class__.__name__) 
#TypeError: isinstance() arg 2 must be a type or tuple of types 

ho trovato una soluzione, ma non funziona con Python 3x

import types 

class A: pass 
a = A() 

print(type(a) == types.InstanceType) 
#AttributeError: 'module' object has no attribute 'InstanceType' 

Soluzione:

if '__dict__' in dir(a) and type(a) is not type: 
+0

Stai chiedendo come determinare se un oggetto è una classe o un'istanza di una classe? – grifaton

+0

InstanceType è classi vecchio stile, che non esistono in 3.x. –

+0

@grifaton, voglio distinguere la classe dall'istanza – Opsa

risposta

11

type(a) è il tipo dell'istanza, ovvero la sua classe. a.__class__ è anche un riferimento alla classe dell'istanza, ma è necessario utilizzare type(a).

types.InstanceType è solo per le classi vecchio stile nelle versioni di Python precedente alla 3.0, in cui tutte le istanze avevano lo stesso tipo. Dovresti utilizzare classi di nuovo stile (derivate da object) in 2.x. In Python 3.0, tutte le classi sono classi di nuovo stile.

+1

(a) funziona solo per le classi di nuovo stile! Se stai utilizzando le classi vecchio stile, verifica se è possibile cambiarle in nuovo stile. Altrimenti usa un .__ class__ che funziona anche con il vecchio stile. @ La risposta di kindall allude già a questo, ma ho pensato che avrei disfatto questo per un po 'di più per le persone. –

1

È perché che il le istanze di classe vecchio stile sono tutte InstanceType, in Python 3.x c'è solo n classi di stile ew, che sono uguali ai tipi. Quindi a sarà di tipo A in Python 3.x. Quindi non è necessario includere InstanceType, quindi non esiste più.

13

La tua domanda non è chiara. Vuoi determinare il "tipo di istanza di classe". Questo può significare due cose. O vuoi determinare se un'istanza è un'istanza di una classe specifica. È possibile farlo in questo modo:

>>> isinstance(a, A) 
True 

È possibile anche ottenere la classe con la chiamata type(), ma che non è generalmente molto utile:

>>> type(a) 
<class '__main__.A'> 

Ma i test che si spettacolo non controllare questo . Invece controllano che tipo è la classe . Ma Python 3 ha solo un tipo di classe. Python 2 e entrambe le classi "old-style" e "new-style", ma Python 3 ha solo classi di nuovo stile, quindi non c'è bisogno di fare questo tipo di controllo in Python 3.

Puoi anche usare metaclassi. In questo caso è possibile trovare la metaclasse controllando la classe del __class__:

>>> from abc import ABCMeta 
>>> class B(metaclass=ABCMeta): pass 
>>> type(B) 
<class 'abc.ABCMeta'> 

Dai vostri commenti, però, sembra che si desidera determinare se un oggetto è un'istanza o meno. Avresti avuto risposte migliori se avessi chiesto che invece ...

In ogni caso, per fare questo si utilizza inspect.isclass:

>>> import inspect 
>>> inspect.isclass(a) 
False 
>>> inspect.isclass(A) 
True 

Questo perché tutto è un caso:

>>> isinstance(type, type) 
True 

Ma non tutto è una classe.

Problemi correlati