Python3中的子类化类型与对象[重复]
Posted
技术标签:
【中文标题】Python3中的子类化类型与对象[重复]【英文标题】:Subclassing type vs object in Python3 [duplicate] 【发布时间】:2018-08-14 23:59:43 【问题描述】:我一直在阅读有关元类的文章,但当谈到 type
和 object
类时,我迷路了。
我知道它们位于层次结构的顶部,并且是用 C 代码实现的。
我也知道type
继承自object
并且object
是type
的一个实例。
在我在 SO 上找到的 answers 之一中,有人说 - 关于 object-type
关系 - 那:
这种相互继承通常是不可能的,但这就是 Python 中这些基本类型的方式:它们违反了规则。
我的问题是为什么要这样实施,这样实施的目的是什么?它解决了什么问题/这种设计有什么好处?难道不能只是 type
或只是 object
类,它位于每个类继承的层次结构的顶部吗?
最后,从object
子类化与从type
子类化之间有什么区别,我什么时候想使用其中一个?
class Foo(object):
pass
对
class Foo(type):
pass
【问题讨论】:
这个答案很有误导性。没有相互继承;答案不能很好地传达实例和子类关系之间的区别。type
是 Python 中的基本元类。 (每个类都是一个对象,一个类的类就是它的元类。)你不应该继承type
,除非你有意创建一个元类。
【参考方案1】:
object
和 type
之间没有交叉继承。事实上,交叉继承是不可能的。
# A type is an object
isinstance(int, object) # True
# But an object is not necessarily a type
isinstance(object(), type) # False
在 Python 中的真实情况是......
一切都是对象
绝对所有,object
是唯一的基本类型。
isinstance(1, object) # True
isinstance('Hello World', object) # True
isinstance(int, object) # True
isinstance(object, object) # True
isinstance(type, object) # True
一切都有类型
任何东西都有一个类型,可以是内置的,也可以是用户自定义的,这个类型可以通过type
获得。
type(1) # int
type('Hello World') # str
type(object) # type
并非所有事物都是类型
这个很明显
isinstance(1, type) # False
isinstance(isinstance, type) # False
isinstance(int, type) # True
type
是它自己的类型
这是type
特有的行为,对于任何其他类都不可重现。
type(type) # type
换句话说,type
是 Python 中唯一的对象 X
,使得 type(X) is X
type(type) is type # True
# While...
type(object) is object # False
这是因为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
【讨论】:
注意:这里的一些“总是”声明仅适用于 Python 3;在 Python 2 中,旧式类有一个完全独立的类型层次结构(type(x)
其中x
是旧式类的一个实例,总是毫无用处地告诉你,该实例的类型是instance
,而不是它是一个实例的类)。
以上所有内容都是正确的,我仔细措辞,所以它在 Python2 和 3 中都是如此。问题是type(Foo()) is Foo
总是正确的。您的示例正确地表明即使isinstance(Foo(), Foo)
为真,它也不是。其余的仍然是正确的,一切都是对象,一切都有类型,type
是唯一属于自己类型的对象。但是,如果我错了,请纠正我!
啊,是的。在重新检查时,即使是旧式类的实例也声称是object
的实例,尽管从object
继承是您创建新式类的方式。不知何故,isinstance(Foo(), object)
为真,即使issubclass(Foo, object)
为假,因为instance
本身是object
的子类。 Py2 类型系统中的hackery 有时有点神奇。 :-)
我还可以在“所有都是对象”下添加:isinstance(type, object) # True
【参考方案2】:
在 Python 中,一切都是对象。每个对象也都有一个类型。事实上,对象的类型也是一个对象,因此也必须有自己的类型。类型有一个特殊的类型,称为type
。这(与任何其他类型一样)是一个对象,因此是 object
的一个实例。
Every 对象是object
的一个实例,包括任何对象的任何类型。所以int
是一个对象,str
也是一个对象,还有更明显的例子,比如1
和'asd'
。您可以在 Python 中引用或分配给变量的任何内容都是 object
的实例。
由于object
是一个类型,它是type
的一个实例。这意味着object
和type
都是彼此的实例。无论您链接的其他答案是什么,这都不是“继承”。该关系与int
和1
之间的关系相同:1
产生的对象是int
的一个实例。这里的怪癖是object
和type
都是彼此的实例。
从 Python 的角度来看,这两个含义不同。 object
类型具有本体论的作用:一切都是对象(不存在其他任何东西)。所以说type
是一个对象只是意味着它存在 就Python 的模型而言。另一方面,object
是所有对象的基本类型,因此它是一种类型。作为一种类型,它必须是 type
的实例,与任何其他对象一样,它也是 object
的实例。
就解释器的实现而言:type
是object
的一个实例这一事实很方便,因为它维护“一切都是对象”,这对于例如在关闭时释放对象。 object
是 type
的一个实例这一事实很有用,因为它可以直接确保它的行为与其他类型对象一样。
【讨论】:
这是很好的信息,有没有更一般的官方知识体系?以上是关于Python3中的子类化类型与对象[重复]的主要内容,如果未能解决你的问题,请参考以下文章
使用PyQt(QMainWindow)使用多重继承进行子类化时python中的MRO [重复]