I used to think that the python follows a ''Class Based Inheritance only (maybe my limited knowledge). But after reading JavaScript which shows the '' Prototype Delegation Based Model, I realized that even python shows some features of prototype based implementations
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
Also Just like in prototype based model it is possible to change prototype of an object at runtime.
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
Even when i delete the explicit reference to class A
del A # deleting the explicit reference on classes
# print(A) --> error
The methods of Class A are still Available for Object b
print(b.square()) # 400
Also when i write b.__class__ = A
print(b.__class__) #<class '__main__.A'>
What i'm saying is current instance is a reference to the type A
Right ?
Because when i print
print(A.__class__) # <type 'type'>
meaning A is a reference to type type.
Since everything in python is an object and i've never created any Object of A
explicitly. Does This delegation model creates the Object Of A
Implicitly ? If not then how does this model work ? also Does the object b
maintain the implicit reference to A or object of A in case it creates an Object as asked above ?
Since everything in python is an object and i've never created any Object of A explicitly. Does This delegation model creates the Object Of A Implicitly ?
No.
If not then how does this model work ?
Each object knows its class (which you can change). Attribute lookup happens dynamically: every time you try to access an attribute (including a method like .square()
), Python first looks to see if the instance has the attribute itself, then looks at whatever __class__
the instance has at that moment, and looks there.
Does the object b maintain the implicit reference to A or object of A in case it creates an Object as asked above ?
When you did b.__class__ = A
, you explicitly gave b
a reference to A
. Note that del A
does not delete the class called A; it deletes the name A
. Since there is another reference to this class (namely b.__class__
), the class still exists and all lookups will happen as usual.
The way it basically works in Python is that each object has a list its superclasses, and those are checked in order every time you try to access an attribute of the object. You can change that list (by assigning to __class__
, or even by changing the __bases__
attribute of its class or superclasses).
I'm not quite sure what you think this has to do with prototypal inheritance. The main thing about prototypal inheritance is that there isn't a distinction between classes and instances; you can create an "instance" directly from any other instance. This isn't really how Python works because classes and their instances have different behavior and you can't straightforwardly "clone" an instance in the same way you create an instance from a class.