Isinstance() и issubclass() возвращают противоречивые результаты
>>> class Hello:
pass
и
>>> isinstance(Hello,object)
True
>>> issubclass(Hello,object)
False
>>> a = Hello()
>>> isinstance(a,object)
True
Как вы объясните isinstance(Hello,object)
возвращает True, а issubclass(Hello,object)
возвращает False
Ответы
Ответ 1
Это потому, что вы используете классы старого стиля, поэтому он не получается из object
. Вместо этого попробуйте:
class Hello(object):
pass
>>> issubclass(Hello,object)
True
Классы старого стиля устарели, и вы больше не должны их использовать.
В Python 3.x все классы являются новыми, а запись (object)
больше не требуется.
Ответ 2
Принятый ответ верный, но, похоже, пропустить важный момент. Встроенные функции isinstance и issubclass задайте два разных вопроса.
isinstance (object, classinfo) спрашивает, является ли объект экземпляром класса (или кортеж классов).
issubclass (class, classinfo) спрашивает, является ли один класс подклассом другого класса (или другого классы).
В любом методе classinfo может быть "классом, типом или кортежем классов, типов и таких кортежей".
Поскольку классы сами являются объектами, isinstance применяется просто отлично. Мы также можем спросить, является ли класс подклассом другого класса. Но мы не должны обязательно ожидать того же ответа от обоих вопросов.
class Foo(object):
pass
class Bar(Foo):
pass
issubclass(Bar, Foo)
#>True
isinstance(Bar, Foo)
#>False
Бар является подклассом Foo, а не экземпляром его. Бар - это экземпляр типа, который является подклассом объекта, поэтому класс Bar является экземпляром объекта.
isinstance(Bar, type)
#>True
issubclass(type, object)
#>True
isinstance(Bar, object)
#>True
Ответ 3
Мой ответ относится к Python 3.
Чтобы расширить ответ на cbare, код ниже был полезен для меня.
>>> class X:
... pass
...
>>> class Y(X):
... pass
...
>>> x = X()
>>> y = Y()
>>> isinstance(x, X) # is object x an instance of class X (or any subclass)?
True
>>> isinstance(x, Y) # is object x an instance of class Y (or any subclass)?
False
>>> isinstance(y, X) # is object y an instance of class X (or any subclass)?
True
>>> isinstance(y, Y) # is object y an instance of class Y (or any subclass)?
True
>>> issubclass(X, X) # is class X a subclass of X (including class X)?
True
>>> issubclass(X, Y) # is class X a subclass of Y (including class Y)?
False
>>> issubclass(Y, X) # is class Y a subclass of X (including class X)?
True
>>> issubclass(Y, Y) # is class Y a subclass of Y (including class Y)?
True
>>> issubclass(type(x), X) # is class of object x a subclass of X (including class X)?
True
>>> issubclass(type(x), Y) # is class of object x a subclass of Y (including class Y)?
False
>>> issubclass(type(y), X) # is class of object y a subclass of X (including class X)?
True
>>> issubclass(type(y), Y) # is class of object y a subclass of Y (including class Y)?
True
>>> issubclass(x.__class__, X) # is class of object x a subclass of X (including class X)?
True
>>> issubclass(x.__class__, Y) # is class of object x a subclass of Y (including class Y)?
False
>>> issubclass(y.__class__, X) # is class of object y a subclass of X (including class X)?
True
>>> issubclass(y.__class__, Y) # is class of object y a subclass of Y (including class Y)?
True
Мы можем видеть, что isinstance(object, class)
правильно относится к наследованию/подклассам.