Opsa
Opsa

Reputation: 459

How to determine the type of class instance

To determine the class, I can do so:

class A: pass    
a = A

type(A) is type #True

or:

import inspect
inspect.isclass(A) 

But how to determine the type of class instance, not knowing the class name?

Something like this:

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

I found one solution, but it does not work with Python 3x

import types

class A: pass
a = A()

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

Solution:

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

Upvotes: 17

Views: 47920

Answers (3)

Lennart Regebro
Lennart Regebro

Reputation: 172349

Your question is a bit unclear. You want to determine the "type of class instance". This can mean two things. Either you want to determine is an instance is an instance of a specific class. You can do that like so:

>>> isinstance(a, A)
True

You can also get the class with the type() call, but that is generally not very useful:

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

But the tests you show doesn't check this. Instead they check what type the class is. But Python 3 only has one type of class. Python 2 and both "old-style" and "new-style" classes, but Python 3 only have new-style classes, so there is no need to make this kind of check in Python 3.

You can also use metaclasses. In that case you can find the metaclass by checking the class's __class__:

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

From your comments, however, it seems that you want to determine if an object is an instance or not. You would have gotten better answers if you asked that instead...

Anyway, to do that you use inspect.isclass:

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

This is because everything is an instance:

>>> isinstance(type, type)
True

But not everything is a class.

Upvotes: 25

kindall
kindall

Reputation: 184345

type(a) is the type of the instance, i.e., its class. a.__class__ is also a reference to the instance's class, but you should use type(a).

types.InstanceType is only for old-style classes in versions of Python pre-3.0, where all instances had the same type. You should be using new-style classes (derived from object) in 2.x. In Python 3.0, all classes are new-style classes.

Upvotes: 19

quantum
quantum

Reputation: 3840

It's because that the old-style class instances are all InstanceType, in Python 3.x there is only new-style classes, which are same as types. So a will be type A in Python 3.x. Then there is no need to include InstanceType, so it doesn't exist any more.

Upvotes: 1

Related Questions