Detect target name in descriptor __set__ method

DG dangets at gmail.com
Thu Jul 23 10:33:55 EDT 2009


On Jul 23, 7:19 am, DG <dang... at gmail.com> wrote:
> On Jul 22, 6:05 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
> wrote:
>
>
>
> > En Wed, 22 Jul 2009 11:01:09 -0300, Rhodri James  
> > <rho... at wildebst.demon.co.uk> escribió:
>
> > > On Wed, 22 Jul 2009 06:02:55 +0100, Gabriel Genellina  
> > > <gagsl-... at yahoo.com.ar> wrote:
>
> > >> class X(object):
> > >>    foo = descriptor()
>
> > >> x = X()
> > >> x.foo = "value"
>
> > > Isn't this going to create a brand new instance attribute x.foo that has  
> > > nothing to do with the descriptor anyway?
>
> > No, it's up to the descriptor __set__ method what happens in this case.  
> > Think of the standard 'property' descriptor, the fset function can do  
> > whatever it wants.
> > Also, a data descriptor takes precedence over any instance attribute of  
> > the same name that might exist.
>
> > --
> > Gabriel Genellin
>
> You might've already thought of this (and it is annoying), but you
> could pass the name through the descriptor's init method.  I believe
> this is the only way besides assigning a metaclass that will look for
> that type of descriptor upon class creation and set the descriptor's
> name at that time.
>
> class A(object):
>     def __init__(self, attr_name):
>         self._name = attr_name
>     def __set__(self, instance, value):
>         self.instance.__dict__[self._name] = value
>         # or something like that...
>
> class B(object):
>     foo = A('foo')

Well of course I think of more alternatives after I post.
1) still annoying... pass the class through a 'registering' function
that will examine all of it's attrs and find the ones that are of your
descriptor type, and assign the attr_name upon that descriptor.name
attribute.

2) I just thought of, and it's kind of a hack is to do this
examination within the '__set__' method.
e.g.

class A(object):
    def __get__(self, instance, owner):
        if instance is None:
            return self
        else:
            # do something different here for instances' access
            return self

    def __set__(self, instance, value):
        cls = instance.__class__
        name = None
        for attr in dir(cls):
            if getattr(cls, attr) is self:
                name = attr
        print name



More information about the Python-list mailing list