isinstance()和issubclass()返回冲突的结果

Tar*_*rik 22 python python-2.x

>>> class Hello:
    pass
Run Code Online (Sandbox Code Playgroud)

>>> isinstance(Hello,object)
True
>>> issubclass(Hello,object)
False
>>> a = Hello()
>>> isinstance(a,object)
True
Run Code Online (Sandbox Code Playgroud)

你如何解释isinstance(Hello,object)返回True,同时issubclass(Hello,object)返回False

cba*_*are 62

接受的答案是正确的,但似乎错过了重要的一点.内置函数isinstanceissubclass问两个不同的问题.

isinstance(object,classinfo)询问对象是否是的实例(或的元组).

issubclass(class,classinfo)询问一个是否是另一个类(或其他类)的子类.

在任何一种方法中,classinfo都可以是"类,类型或元组和类似元组的类,类或元组".

由于类本身就是对象,因此isinstance适用.我们还可以问一个类是否是另一个类的子类.但是,我们不一定期望从这两个问题得到同样的答案.

class Foo(object):
    pass

class Bar(Foo):
    pass

issubclass(Bar, Foo)
#>True
isinstance(Bar, Foo)
#>False
Run Code Online (Sandbox Code Playgroud)

Bar是Foo的子类,而不是它的一个实例.Bar是类型的实例,它是object的子类,因此类Bar是object的实例.

isinstance(Bar, type)
#>True
issubclass(type, object)
#>True
isinstance(Bar, object)
#>True
Run Code Online (Sandbox Code Playgroud)

  • 非常清楚.谢谢你这个额外的答案. (3认同)

Mar*_*ers 22

这是因为你使用的是旧式类,所以它并非源自object.试试这个:

class Hello(object):
    pass

>>> issubclass(Hello,object)
True
Run Code Online (Sandbox Code Playgroud)

旧式类已弃用,您不应再使用它们.

在Python 3.x中,所有类都是新式的,(object)不再需要编写.

  • 旧样式类是`types.ClassType`类型的实例(不是子类!).作为所有类型,它是`object`的子类,这就是为什么任何旧样式类都是`object`类型的实例. (6认同)
  • 值得注意的是:这适用于Python 2.在Python 3中,不需要明确地从`object`派生. (5认同)

kev*_*rpe 11

我的回答与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
Run Code Online (Sandbox Code Playgroud)

我们可以看到isinstance(object, class)正确地尊重继承/子类.

  • 这很有用,但是您可以重做您的答案以使用不同的名称吗?例如,基类的“Person”具有名为“john”的实例,子类的“Scientist”具有名为“einstein”的实例。 (2认同)