Ryan wrote: > In the context of descriptors, the __set__ method is not called for > class attribute access. __set__ is only > called to set the attribute on an instance instance of the owner class > to a new value, value. WHY? Is there some other mechanism for > accomplishing this outcome. This subtle difference from __get__cost me > some time to track down. Might think about pointing that out the > documentation. > > > class RevealAccess(object): > """A data descriptor that sets and returns values > normally and prints a message logging their access. > """ > > def __init__(self, initval=None, name='var'): > self.val = initval > self.name = name > > def __get__(self, obj, objtype): > print 'Retrieving', self.name > return self.val > > def __set__(self, obj, val): > print 'Updating' , self.name > self.val = val > > class MyClass(object): > x = RevealAccess(10, 'var "x"') > y = 5 > > print MyClass.x > MyClass.x = 20 > print MyClass.x > MyClass.x = 30 > print MyClass.x > > Retrieving var "x" > 10 > 20 > 30 > > I am at a lost on how to intercept class attribute sets. Can anyone > help :-/
A class is just an instance of its metaclass, so you could move the descriptor into the metaclass to see the expected behaviour in the class: >>> class A: ... class __metaclass__(type): ... x = RevealAccess(10, 'var "x"') ... >>> A.x = 42 Updating var "x" >>> A.x Retrieving var "x" 42 However: >>> A().x Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'A' object has no attribute 'x' So you'd need two descriptors if you want to intercept variable access on both the instance and class level. -- http://mail.python.org/mailman/listinfo/python-list