Prototype Delegation Based模型如何在Python中运行?

时间:2016-04-17 04:35:14

标签: python oop delegates delegation

我曾经认为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对象的隐式引用,以防它按上面的要求创建一个对象?

2 个答案:

答案 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访问它们。