isinstance() 和 issubclass() 返回冲突结果
你怎么解释 isinstance(Hello,object)
返回 True,而 issubclass(Hello,object)
返回 False 呢?
>>> class Hello:
pass
还有
>>> isinstance(Hello,object)
True
>>> issubclass(Hello,object)
False
>>> a = Hello()
>>> isinstance(a,object)
True
4 个回答
19
我的回答是关于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)
能够正确处理继承和子类的关系。
101
这个被接受的答案是对的,但似乎漏掉了一个重要的点。内置的函数 isinstance 和 issubclass 其实是在问两个不同的问题。
isinstance(对象, 类信息) 是在问一个 对象 是否是某个 类 的实例(或者是多个类的组合)。
issubclass(类, 类信息) 是在问一个 类 是否是另一个类(或者多个类)的子类。
在这两种方法中,类信息 可以是“类、类型,或者多个类、类型的组合”。
因为类本身也是对象,所以使用 isinstance 是完全可以的。我们也可以问一个类是否是另一个类的子类。不过,我们不应该期待这两个问题会得到相同的答案。
class Foo(object):
pass
class Bar(Foo):
pass
issubclass(Bar, Foo)
#>True
isinstance(Bar, Foo)
#>False
Bar 是 Foo 的子类,而不是它的实例。Bar 是 type 的一个实例,而 type 是 object 的子类,因此类 Bar 是 object 的一个实例。
isinstance(Bar, type)
#>True
issubclass(type, object)
#>True
isinstance(Bar, object)
#>True
27
这是因为你在使用旧式类,所以它没有从 object
这个基础类派生。你可以试试这个:
class Hello(object):
pass
>>> issubclass(Hello,object)
True
旧式类已经不推荐使用了,你不应该再用它们。
在 Python 3.x 中,所有的类都是新式类,写 (object)
已经不再需要了。