Reputation: 459
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
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
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
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