I'm trying to better understand descriptors and I've got a few questions still after reading some sites. Here is what I 'think', but please let me know if any of this is wrong as I'm sure it probably is.

First when accessing an attribute on a class or instance it must be found. For an instance, it's __dict__ is first search. If not found the class and base class __dict__ are searched. For a class, the __dict__ and base classes __dict__ are search.

If assigning, and the attribute is found and is not a descriptor or if the attribute is not found, then the assignment will occur in the __dict__ of the class or instance. If it is found and is a descriptor, then __set__ will be call.

For reading, if the attribute is found and is a descriptor, __get__ will be called, passing the object (if it is an instance) and class. If it is not a descriptor, the attribute will be returned directly.

Class methods are just functions:

class C(object):
   def F(self):
      pass

C.__dict__['F'] # function object ...

But functions are descriptors:

C.__dict__['F'].__get__ # method wrapper ...

def f1():
   pass

f1.__get__ # method wrapper ...

When a lookup is done it uses this descriptor to make a bound or unbound method:

c=C()

C.F # unbound method object, expects explicit instance when calling the function c.F # bound method object provides instance implicitly when calling the function

This is also done when adding to the classes:

C.f1 = f1

f1 # function
C.f1 # unbound method
c.f1 # bound method

To prevent this it has to be decorated so the descriptor doesn't cause the binding:

C.f2 = staticmethod(f1)
C.f2 # functon
c.f2 # function

Here is a question, why don't instance attributes do the same thing?

c.f3 = f1
c.f3 # function, not bound method

So it is not calling the __get__ method for c.f3 After it finds c.f3 in c.__dict__, and since it has a getter, shouldn't it call the __get__ to return the bound method. It is good that it doesn't I know, but I just want to know why it doesn't from an implementation view.


Brian Vanderburg II
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to