我曾经认为python仅遵循'Class Based Inheritance(可能是我有限的知识)。但在阅读了显示'Prototype Delegation Based Model的JavaScript之后,我意识到甚至python都会显示基于原型的实现的一些功能
class A(object):
def __init__(self, a):
self.a = a
def square(self):
return self.a * self.a
a = A(10)
print(a.a) #10
A.b = 20 # a new Property of the class
print(a.b) # 20 - available via "delegation" for the "a" instance
同样在基于原型的模型中,可以在运行时更改对象的原型。
class B(object):
""" Empty class B"""
pass
b = B() # an instance of the class B
b.__class__ = A # changing class (prototype) dynamically
print (b.__dict__) # {}
b.a = 20 # create a new property
print(b.square()) # 400 - method of the class A is available
即使我删除了对A类的明确引用
del A # deleting the explicit reference on classes
# print(A) --> error
A类方法仍可用于对象b
print(b.square()) # 400
当我写b.__class__ = A
print(b.__class__) #<class '__main__.A'>
我所说的当前实例是对type A
对的引用?
因为当我打印
print(A.__class__) # <type 'type'>
含义A是对类型类型的引用。
因为python中的所有内容都是一个对象,我从未明确地创建任何A
的对象。此委托模型是否隐式创建A
的对象?如果没有,那么这个模型是如何工作的?对象b
是否保持对A或A对象的隐式引用,以防它按上面的要求创建一个对象?
答案 0 :(得分:2)
因为python中的所有内容都是一个对象,并且我从未明确地创建任何A的Object。此委托模型是否隐式创建了对象?
没有
如果没有,那么这个模型是如何工作的?
每个对象都知道它的类(你可以改变它)。属性查找动态发生:每次尝试访问属性(包括.square()
之类的方法)时,Python首先会查看实例是否具有属性本身,然后查看实例具有的__class__
那一刻,看着那里。
如果上面要求它创建一个Object,对象b是否保持对A或A对象的隐式引用?
当您b.__class__ = A
时,您明确地向b
提供了对A
的引用。请注意,del A
不删除名为A的类;它会删除名称 A
。由于还有另一个对此类的引用(即b.__class__
),因此该类仍然存在,并且所有查找都将照常进行。
它在Python中的基本工作方式是每个对象都有一个列表的超类,每次尝试访问对象的属性时都会按顺序检查它们。您可以更改该列表(通过分配到__class__
,甚至更改其类或超类的__bases__
属性。)
我不太确定你认为这与原型继承有什么关系。关于原型继承的主要问题是类和实例之间没有区别;你可以创建一个&#34;实例&#34;直接来自任何其他实例。这并不是Python的工作方式,因为类及其实例具有不同的行为,您无法直接克隆&#34;实例的方式与从类创建实例的方式相同。
答案 1 :(得分:0)
类共享其基础的机制
属性如下。
访问属性时,该值可能来自几个不同的位置。
首先检查实例,如果什么都不知道,搜索将移动到
实例的类而不是继承
链。例如,obj.attr
可能是实例attr
的{{1}}属性,如果它在obj
中设置,或者稍后在类定义中动态地__init__
设置(典型的方法)。
因此,如果你执行attr
,则可以引用A的属性,它们是内存中的对象。 obj.__class__ = A
使名称del A
无法使用,但对象只有在无法访问时才会被垃圾回收。 A
现在无法访问,但不是它可以通过A
访问它们。