__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