From: kedra marbun on
On Jul 5, 7:49 am, Gregory Ewing <greg.ew...(a)canterbury.ac.nz> wrote:
> kedra marbun wrote:
> > now, i'm asking another favor, what about the 2nd point in my 1st post?
>
> Your original post has dropped off my newsscope, so
> you'll have to remind me what the 2nd point was.
>
> --
> Greg

it's like 'name', it's about info that i think should be passed to
descriptor's __{get|set|delete}__. i wonder what are the reasons for
not passing the class on which the descriptor is attached to, what
pattern is encouraged by this?
From: Steven D'Aprano on
On Mon, 05 Jul 2010 21:12:47 -0700, kedra marbun wrote:

> On Jul 5, 7:49 am, Gregory Ewing <greg.ew...(a)canterbury.ac.nz> wrote:
>> kedra marbun wrote:
>> > now, i'm asking another favor, what about the 2nd point in my 1st
>> > post?
>>
>> Your original post has dropped off my newsscope, so you'll have to
>> remind me what the 2nd point was.
>>
>> --
>> Greg
>
> it's like 'name', it's about info that i think should be passed to
> descriptor's __{get|set|delete}__. i wonder what are the reasons for not
> passing the class on which the descriptor is attached to, what pattern
> is encouraged by this?



Perhaps I'm missing the context, but since the descriptor is passed the
instance, you can easily get the class with type(self) or self.__class__.
There's no need to pass the class as a separate argument.



--
Steven

From: Rami Chowdhury on
On Monday 05 July 2010 21:10:51 kedra marbun wrote:
> On Jul 5, 3:42 pm, Bruno Desthuilliers <bruno.
>
> 42.desthuilli...(a)websiteburo.invalid> wrote:
> > kedra marbun a écrit :
> > > i'm confused which part that doesn't make sense?
> > > this is my 2nd attempt to py, the 1st was on april this year, it was
> > > just a month, i'm afraid i haven't got the fundamentals right yet. so
> > > i'm gonna lay out how i got to this conclusion, CMIIW
> > >
> > > **explanation of feeling (0) on my 1st post**
> > > to me, descriptor is a particular kind of delegation, it takes the job
> > > of coding the delegation by having a contract with programmers that
> > > the tree meta operations (get, set, del) on attr are delegated to the
> > > obj that is bound to the attr
> > > are we agree that descriptor is a kind of delegation?
> > >
> > > the mechanism that makes descriptor works is in __getattribute__,
> > > __setattr__, __delattr__ of 'object' & 'type'
> > >
> > > now, if i want a single descriptor obj to be delegated to multiple
> > > tasks, i can't do it since __get__ doesn't get info that can be used
> > > to determine which task to do
> > > i must have diff descriptor obj for each task
> > >
> > > class Helper:
> > > def __init__(self, name):
> > > self.name = name
> > > def __get__(self, ins, cls):
> > > if self.name == 'task0': ...
> > > elif self.name == 'task1': ...
> > > else: ...
> >
> > Replacing such "big switch" code with polymorphic dispatch is one of the
> > goals (and feature) of OO. This should be:
> >
> > class Task0(object):
> > def __get__(self, obj, cls):
> > # code here
> >
> > class Task1(object):
> > def __get__(self, obj, cls):
> > # code here
> >
> > class A(object):
> > task0 = Task0()
> > task1 = Task1()
> >
> > If you have common code to share between TaskO and Task1 then factor it
> > out into a base class.
> >
> > > if __get__ receives the name, then i could do
> > >
> > > class Helper:
> > > def __get__(self, ins, cls, name):
> > > ...
> > >
> > > class a:
> > > task0 = task1 = Helper()
> >
> > Yuck.
>
> what's so 'Yuck' about it? ;)
> i guess i need a strong stmt: is descriptor a kind of delegation? or
> is it not?

Thanks for posting the code sample -- it makes your meaning a great deal
clearer. No, descriptors are not delegation as in your sample**, although they
are very flexible and could be used to implement that if you wanted.

> * if it's not, then there's nothing to be argued, the name
> 'descriptor' is perfectly fit: descriptor obj describes attr of class,
> with 'describe' translates to: . = del, in py vocabularies. then, to
> think a single descriptor obj describing a single attr is acceptable,
> it's a common sense

** As I understand it, anyway -- someone please correct me if I'm wrong.


----
Rami Chowdhury
"Never attribute to malice that which can be attributed to stupidity." --
Hanlon's Razor
+1-408-597-7068 / +44-7875-841-046 / +88-01819-245544
From: Bruno Desthuilliers on
kedra marbun a �crit :
> On Jul 5, 3:42 pm, Bruno Desthuilliers <bruno.
> 42.desthuilli...(a)websiteburo.invalid> wrote:
>> kedra marbun a �crit :
>>
>>
>>
>>> i'm confused which part that doesn't make sense?
>>> this is my 2nd attempt to py, the 1st was on april this year, it was
>>> just a month, i'm afraid i haven't got the fundamentals right yet. so
>>> i'm gonna lay out how i got to this conclusion, CMIIW
>>> **explanation of feeling (0) on my 1st post**
>>> to me, descriptor is a particular kind of delegation, it takes the job
>>> of coding the delegation by having a contract with programmers that
>>> the tree meta operations (get, set, del) on attr are delegated to the
>>> obj that is bound to the attr
>>> are we agree that descriptor is a kind of delegation?
>>> the mechanism that makes descriptor works is in __getattribute__,
>>> __setattr__, __delattr__ of 'object' & 'type'
>>> now, if i want a single descriptor obj to be delegated to multiple
>>> tasks, i can't do it since __get__ doesn't get info that can be used
>>> to determine which task to do
>>> i must have diff descriptor obj for each task
>>> class Helper:
>>> def __init__(self, name):
>>> self.name = name
>>> def __get__(self, ins, cls):
>>> if self.name == 'task0': ...
>>> elif self.name == 'task1': ...
>>> else: ...
>> Replacing such "big switch" code with polymorphic dispatch is one of the
>> goals (and feature) of OO. This should be:
>>
>> class Task0(object):
>> def __get__(self, obj, cls):
>> # code here
>>
>> class Task1(object):
>> def __get__(self, obj, cls):
>> # code here
>>
>> class A(object):
>> task0 = Task0()
>> task1 = Task1()
>>
>> If you have common code to share between TaskO and Task1 then factor it
>> out into a base class.
>>
>>> if __get__ receives the name, then i could do
>>> class Helper:
>>> def __get__(self, ins, cls, name):
>>> ...
>>> class a:
>>> task0 = task1 = Helper()
>> Yuck.
>
> what's so 'Yuck' about it? ;)

It's an implicit, obfuscated and overcomplicated way to do a very simple
thing. To be true, I just don't see the point of this pattern - Python
has better solutions for delegation (cf the __getattr__ method), and
that's not what descriptors are for.


> i guess i need a strong stmt: is descriptor a kind of delegation? or
> is it not?

The descriptor protocol is the primary support for computed attributes.
As such it can be used as a support for delegation, but it's not "a kind
of delegation" by itself.

> * if it is a kind of delegation, then the code that you labeled as
> 'Yuck' is just a result of applying delegation
> what's wrong with delegating multiple tasks to a single obj?

Nothing wrong with delegating multiple tasks to a single object - but
not that way. If you want to use descriptors to specify which tasks
should be delegated, you'd be better doing it more explicitely - that
is, only use the descriptor as a gateway, and use one descriptor per task.

Else just use __getattr__ !-)

Sorry, I don't have much time to elaborate on this now.

> that code is similar to this
>
> class Helper:
> def do_this(self, ins): ...
> def do_that(self, ins): ...
>
> class a:
> delegate = Helper()
> def task0(self): self.delegate.do_that(self)
> def task1(self): self.delegate.do_this(self)
>

It's not similar. This second example is explicit, and doesn't couple
Helper to a.


My 2 cents.
From: Bruno Desthuilliers on
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.