Почему isinstance(nonnewstyle, object) возвращает true в Python 2.X?

Я читаю учебник по Python, и он охватывает различия классов нового стиля. Обратите внимание на следующий код в Python 2.X в интерпретаторе, который использует классические классы:

class C: pass
X = C()
isinstance(X, object) #returns true
isinstance(C, object) #returns true

(Чтобы использовать классы нового стиля, нужно явно наследовать класс объекта в 2.X)

Так как же объект, который не является производным (как в классических классах) от класса объекта, может быть экземпляром объекта? Что происходит за кулисами в случае 3.X и 2.X?

Что касается того, является ли это дублирующим вопросом: я уже знал, что все технически было объектом, мне было интересно, как несоответствие явно обрабатывается при разработке самого Python, а не принимать результаты isinstance как должное.

3 ответа

Решение

Все в Python является примером object, в том числе object сам:

>>> isinstance(object, object)
True

Это потому что type.__instancecheck__ крюк возвращается True когда прошло в object за self, независимо от того, что другой аргумент (помните, что специальные методы смотрятся на type(something), не на something сам и есть self прошло вручную).

Если вы хотите проверить классы старого стиля, гораздо полезнее проверить, является ли класс экземпляром type или подкласс object:

>>> isinstance(C, type)
False
>>> issubclass(C, object)
False

Любой из этих тестов верен для классов нового стиля:

>>> class Newstyle(object): pass
...
>>> isinstance(Newstyle, type)
True
>>> issubclass(Newstyle, object)
True

Например, проверьте, являются ли они экземпляром types.InstanceType:

>>> isinstance(X, InstanceType)
True

X является экземпляром старого стиля класса C старого стиля, который не является подклассом object,

Тем не менее, все объекты, даже экземпляры старого стиля, являются экземплярами некоторого типа (иначе классом нового стиля). Тип всех экземпляров старого стиля types.InstanceType; вместе с types.ClassTypeтип классов старого стиля, эти два типа отвечают за реализацию системы классов старого стиля.

types.InstanceType это подкласс object, как и все классы нового стиля. isinstance(X, object) возвращает true не потому, что класс X в старом стиле наследуется от object, но потому что его новый стиль класса делает.

Вы наверное путаете isinstance с issubclass, Классы старого стиля не происходят от object Это означает, что результат issubclass(C, object) будет False, Новые классы стиля, с другой стороны, всегда содержат object (прямо или косвенно) в качестве базового класса.

Все является примером object, Так делаю isinstance(C, object) или же isinstance(x, object) всегда будет True,

Другие вопросы по тегам