__set__ method is not called for class attribute access
Fuzzyman
fuzzyman at gmail.com
Wed Aug 10 10:36:20 EDT 2011
On Aug 5, 1:16 pm, Duncan Booth <duncan.bo... at invalid.invalid> wrote:
> Ryan <heni... at yahoo.com> 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 :-/
>
> The descriptor protocol only works when a value is being accessed or set
> on an instance and there is no instance attribute of that name so the
> value is fetched from the underlying class.
>
That's not true. Properties, for example, can be got or set even when
they shadow an instance attribute. You're (probably) thinking of
__getattr__ which isn't invoked when an instance attribute exists.
Also, the descriptor protocol *is* invoked for getting an attribute
from a class - but not when setting a class attribute. An unfortunate
asymmetry. It just wasn't considered as a use case when the descriptor
protocol was implemented.
Michael
--
http://voidspace.org.uk/
More information about the Python-list
mailing list