Как определить тип экземпляра класса

Чтобы определить класс, я могу сделать это:

class A: pass    
a = A

type(A) is type #True

или

import inspect
inspect.isclass(A) 

Но как определить тип экземпляра класса, не зная имя класса?

Что-то вроде этого:

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

Я нашел одно решение, но оно не работает с Python 3x

import types

class A: pass
a = A()

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

Решение:

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

Ответ 1

type(a) - тип экземпляра, т.е. его класс. a.__class__ также является ссылкой на класс экземпляра, но вы должны использовать type(a).

types.InstanceType предназначен только для классов старого стиля в версиях Python pre-3.0, где все экземпляры имеют один и тот же тип. Вы должны использовать классы нового стиля (полученные из object) в 2.x. В Python 3.0 все классы являются классами нового стиля.

Ответ 2

Ваш вопрос немного неясен. Вы хотите определить "тип экземпляра класса". Это может означать две вещи. Либо вы хотите определить, является ли экземпляр экземпляром определенного класса. Вы можете сделать это так:

>>> isinstance(a, A)
True

Вы также можете получить класс с вызовом type(), но это, как правило, не очень полезно:

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

Но тесты, которые вы показываете, не проверяют это. Вместо этого они проверяют тип класса. Но у Python 3 есть только один тип класса. Python 2 и оба класса "старый стиль" и "новый стиль", но Python 3 имеет только классы нового стиля, поэтому нет необходимости делать такую ​​проверку в Python 3.

Вы также можете использовать метаклассы. В этом случае вы можете найти метакласс, проверив класс __class__:

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

Из ваших комментариев, однако, кажется, что вы хотите определить, является ли объект экземпляром или нет. Вы бы получили лучшие ответы, если бы попросили об этом...

Во всяком случае, для этого вы используете inspect.isclass:

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

Это потому, что все это экземпляр:

>>> isinstance(type, type)
True

Но не все это класс.

Ответ 3

Это потому, что экземпляры класса старого стиля - это InstanceType, в Python 3.x есть только классы нового стиля, которые аналогичны типам. Таким образом, a будет типом A в Python 3.x. Тогда нет необходимости включать InstanceType, поэтому он больше не существует.