Почему 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
,