delegation pattern via descriptor

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Thu Jul 8 05:02:47 EDT 2010


kedra marbun a écrit :
> On Jul 7, 2:46 am, Bruno Desthuilliers
> <bdesth.quelquech... at free.quelquepart.fr> wrote:
>> Gregory Ewing a écrit :
>>
>>> Bruno Desthuilliers wrote:
>>>> kedra marbun a écrit :
>>>>> if we limit our discussion to py:
>>>>> why __{get|set|delete}__ don't receive the 'name' & 'class' from
>>>>> __{getattribute|{set|del}attr}__
>>>>> 'name' is the name that is searched
>>>> While it would have been technically possible, I fail to imagine any use
>>>> case for this.
>>> I think he wants to have generic descriptors that are
>>> shared between multiple attributes, but have them do
>>> different things based on the attribute name.
>> I already understood this, but thanks !-)
>>
>> What I dont understand is what problem it could solve that couldn't be
>> solved more simply using the either _getattr__ hook or hand-coded
>> delegation, since such a descriptor would be so tightly coupled to the
>> host class that it just doesn't make sense writing a descriptor for this.
> 
> yeah, i finally can agree descriptor isn't supposed to be used as
> delegation in general, it should be the job of __getattr__
> 
> however i still think passing name would open up some other
> possibilities of use

Nothing prevents you to pass a "name" to the descriptor instance when 
instanciating it, ie:

class Desc(object):
     def __init__(self, name):
         self.name = name
    def __get__(self, inst, cls):
        # ...
    def __set__(self, inst, value):
        # ...


class Foo(object):
     bar = Desc("bar")
     baaz = Desc("baaz")

Ok, this is not necessarily what you were looking for, but it's IMHO 
less brittle than relying on which attribute name was looked up (which 
is something the descriptor shouldn't have to care about).

> 
> btw, is there a common approach to let the interface of a class that
> uses __getattr__, to include names that are delegated?

In Python 2.x, not that I know (but it may have passed under my radar). 
If what you want it to automate delegation of a set of methods without 
too much manual coding, you can use a custom metaclass that will add the 
relevant methods to the class, based on (ie) a list (or mapping) of 
methods names. But that might be a bit overkill.

> class A:
> 	def do_this(self): ...
> 
> class B:
> 	a = A()

I don't see the point of using delegation on a class attribute. That's 
typically what inheritance is for.

> 	def do_that(self): ...
> 
> 	def __getattr__(self, name):
> 		try:
> 			return types.MethodType(getattr(self.a, name), self)

Err... Did you try the simple way ?
                         return getattr(self.a, name)




More information about the Python-list mailing list