Python3中的子类型与对象的子类化

an0*_*nym 3 python inheritance metaclass

我一直在阅读有关元类的内容,type而且在object课堂上我迷路了.

我知道它们位于层次结构的顶层,并且它们是用C代码实现的.我也明白,type继承自objectobject是一个实例type.

在我发现的其中一个答案中,有人说 - 在object-type关系中 - 说:

这种相互继承通常是不可能的,但这就是Python中这些基本类型的方式:它们违反了规则.

我的问题是为什么以这种方式实现,这种实现的目的是什么?它解决了什么问题/这个设计有什么好处?难道不是只是type或只是object在每个类继承的层次结构顶部的类?

最后,子类化object与子类化之间是否有任何区别type,何时我想使用另一个?

class Foo(object):
    pass
Run Code Online (Sandbox Code Playgroud)

VS

class Foo(type):
    pass
Run Code Online (Sandbox Code Playgroud)

Oli*_*çon 8

object和之间没有交叉继承type.事实上,交叉继承是不可能的.

# A type is an object
isinstance(int, object) # True

# But an object is not necessarily a type
isinstance(object(), type) # False
Run Code Online (Sandbox Code Playgroud)

Python中的真实情况是......

一切都是对象

绝对一切,object是唯一的基本类型.

isinstance(1, object) # True
isinstance('Hello World', object) # True
isinstance(int, object) # True
isinstance(object, object) # True
Run Code Online (Sandbox Code Playgroud)

一切都有类型

一切都有一个类型,无论是内置的还是用户定义的,这种类型都可以获得type.

type(1) # int
type('Hello World') # str
type(object) # type
Run Code Online (Sandbox Code Playgroud)

并非一切都是一种类型

那个是相当明显的

isinstance(1, type) # False
isinstance(isinstance, type) # False
isinstance(int, type) # True
Run Code Online (Sandbox Code Playgroud)

type 是它自己的类型

这是特定于type并且对于任何其他类不可再现的行为.

type(type) # type
Run Code Online (Sandbox Code Playgroud)

换句话说,type是Python中唯一的对象

type(type) is type # True

# While...
type(object) is object # False
Run Code Online (Sandbox Code Playgroud)

这是因为type它是唯一的内置元类.元类只是一个类,但它的实例也是类本身.所以在你的例子中......

# This defines a class
class Foo(object):
    pass

# Its instances are not types
isinstance(Foo(), type) # False

# While this defines a metaclass
class Bar(type):
    pass

# Its instances are types
MyClass = Bar('MyClass', (), {})

isinstance(MyClass, type) # True

# And it is a class
x = MyClass()

isinstance(x, MyClass) # True
Run Code Online (Sandbox Code Playgroud)

  • 没错.在重新检查时,即使是旧式类的实例也声称是`object`的实例,尽管继承自`object`是你创建一个新类的方式.不知何故,`isinstance(Foo(),object)`是真的,即使`issubclass(Foo,object)`是假的,因为`instance`本身是`object`的子类.Py2型系统中的hackery有时会非常神奇.:-) (2认同)