Почему в Python 2 экземпляры классов старого стиля по-прежнему являются экземплярами object
, даже если они явно не наследуются от object
?
class OldClass:
pass
>>> isinstance(OldClass(), object)
True
Прежде чем тестировать это, я бы пришел к выводу, что isinstance(x, object) == True
будет означать, что x
является экземпляром подкласса object
и, следовательно, экземпляром класса нового стиля, но похоже, что все объекты в Python 2 являются экземплярами object
(да, я знаю как очевидно это звучит)
Копаясь дальше, я обнаружил еще одно, казалось бы, странное поведение:
>>> issubclass(OldClass, object)
False
У меня сложилось впечатление, что isinstance(x, SomeClass)
практически эквивалентно issubclass(x.__class__, SomeClass)
, но, видимо, я что-то упускаю.
Foo
также является экземпляромobject
, как он был спроектирован таким образом, чтобы ответить, почемуFoo
не является подклассомobject
? - person Markus Meskanen   schedule 15.06.2017issubclass(OldClass, object) == False
в примере OP? - person Markus Meskanen   schedule 15.06.2017object
, но классы старого стиля имеют разделенную реализацию. Сам класс является экземпляромclassobj
, а его экземпляры являютсяinstance
объектами. - person Eryk Sun   schedule 15.06.2017isinstance
ожидает объект в качестве первого аргумента,issubclass
ожидает класс/тип в качестве первого аргумента) - person Billy   schedule 15.06.2017isinstance()
иissubclass
всегда должно бытьissubclass(Foo, Bar) == isinstance(Foo(), Bar)
, но здесь это не так, поэтому OP задал вопрос. - person Markus Meskanen   schedule 15.06.2017object
, но не его подклассами. Этот вопрос о том, почему экземпляр класса старого стиля также является экземпляромobject
, что абсолютно бессмысленно, поскольку класс старого стиля не является подклассомobject
. - person Markus Meskanen   schedule 15.06.2017issubclass(OldClass, OtherOldClass)
, иisinstance(OldClass(), OldClass)
имеют особый регистр. Для последнего он должен получить атрибут__class__
из экземпляраOldClass()
, чтобы проверить формуissubclass
в специальном регистре. Мы можем углубиться в детали реализации в CPython, но я думаю, что достаточно знать, что междуOldClass
иOldClass()
нет связи на основе типов. Только в Python 2.2 типы и классы были унифицированы таким образом, чтоtype(NewClass()) is NewClass
. - person Eryk Sun   schedule 15.06.2017python-internals
, разве этот вопрос не об этом? Похоже, что Python делает что-то странное сissubclass()
иisinstance()
, что не соответствует ожиданиям непрофессионала, и требует дальнейшего изучения того, как именно классы старого стиля работают сissubclass()
иisinstance()
. Может я ошибся с тегом, просветите меня, если это так. - person Markus Meskanen   schedule 15.06.2017