why the super class can access the subclass's attribute

Chris Rebert clp2 at rebertia.com
Thu Jan 21 02:38:56 EST 2010


On Wed, Jan 20, 2010 at 8:56 PM, yousay <qq263020776 at gmail.com> wrote:
> I have sees aprogram like this ,i confusing why super class can access
> the subclass's attribute

To make this easy to understand, I'm going to ***drastically*** oversimplify.
With that disclaimer out of the way...

When you access an instance attribute, as in self.result, Python
actually returns self.__dict__["result"]; that is, it does a
dictionary lookup using the attribute name as a string as the key;
instance attribute assignment works analogously. Every object has a
special dictionary associated with it that is used to store its
instance attributes; this dictionary can itself be accessed through
the __dict__ attribute. (And if you're about to ask how the __dict__
attribute gets looked up, well, it's magic™!)

This "instance attribute access is just dictionary manipulation"
principle is universal, even in subclasses, superclasses, and
unrelated objects. Thus, in both Worker and its superclass MyThread,
accessing the `result` instance attribute manipulates the very same
dictionary (self.__dict__) and thus works exactly the same in both
cases.

So, essentially, `result` is accessible to MyThread because there's
nothing to prevent it from being accessible there.

Other related principles that may aid in your understanding (these are
not oversimplified):
- Attribute lookups all happen dynamically at runtime
- Python has no language-enforced notion of `protected` or `private`
attributes; everything's public
- Python is dynamically typed and thus does no compile-time typechecking

Cheers,
Chris
--
Simplifications include overlooking __slots__, metaclasses,
__getattribute__, and instance.class_attribute, among others.
http://blog.rebertia.com

> ,this is the program,thanks in advance:
> class MyThread(threading.Thread):
>    def join(self):
>        super(MyThread,self).join()
>        return self.result
>
> class Worker(MyThread):
>    import random
>    import pdb
>    pdb.set_trace()
>    def run(self):
>        total = 0
>        for i in range(random.randrange(10,100)):
>            total +=i
>        self.result = total



More information about the Python-list mailing list