[Python-ideas] Name mangling and code repetition (with cooperative inheritance use case)
Zahari Petkov
zarchaoz at gmail.com
Tue Apr 9 06:24:10 CEST 2013
You give me here some very nice ideas, which I am going to explore
more tomorrow, including trying out ChainMap. Thanks for working on
this and suggesting those.
Back on the original topic, as I understand from the Guido's answers
the `__private` attributes have a very specific purpose (e.g. the one
explained in the tutorial) and it is not intended as a generic tool
like other language features are. Although my code is working
correctly, since I am going outside of the indented boundaries, it is
normal to hit some rough corners. That invalidates my original idea
about eliminating the duplicated code case, since it is a result of
wrong presumption - that '__private' attributes is a generic tool.
Probably no need to continue further with the `__private` discussion.
It is anyway with little practical use.
Thanks again guys,
Zahari
On Tue, Apr 9, 2013 at 6:44 AM, Joao S. O. Bueno <jsbueno at python.org.br> wrote:
> I see -
> in that case, you can have a class decorator, or even a function as a
> metaclass, that creates a new _dispatch table for every subclass - If
> you are using Python 3.3 you can enven use a collections.ChainMap for
> that to avoid duplicating the dictionary data once for each class.
>
> I actually got such an example with decorators working before I read
> Terry's message and thought a single - root-class based dict could
> cover all use cases:
>
> https://gist.github.com/jsbueno/6f14167b8c4631d0baa7
>
> Using a metaclass instead of a decorator would free you from
> decorating every class -
> and it could just be a function receiving (name, bases, dct) as
> parameters that would call "type" instead of a "real" metaclass, since
> the changes can be made after the class is created by a plain call to
> "type".
>
> js
> -><-
>
>
>
> On 8 April 2013 23:39, Zahari Petkov <zarchaoz at gmail.com> wrote:
>> Right, I forgot to mention that ordering is important - this is why a
>> priority sequence is needed,
>> not a mapping.
>>
>> The case is that a subclass may need to be rendered in a different way
>> than a superclass.
>>
>> class VerySpecialInt(int):
>> pass
>>
>> and
>>
>> class VerySpecialIntRenderer(Renderer):
>> pass
>>
>> this needs to go before the IntRenderer in the mro chain, or at the
>> front in the composition example.
>>
>> Otherwise the dict dispatch would be perfectly ok, and thanks for
>> sharing this gist.
>>
>>
>> On Tue, Apr 9, 2013 at 5:32 AM, Joao S. O. Bueno <jsbueno at python.org.br> wrote:
>>> On 8 April 2013 23:15, Terry Jan Reedy <tjreedy at udel.edu> wrote:
>>>> On 4/8/2013 9:54 PM, Zahari Petkov wrote:
>>>>>
>>>>> Hello again,
>>>>>
>>>>> Unfortunatelly, the idea cannot be expressed in the simplest way, since
>>>>> this
>>>>> leads to confusion, so I present three short gists and explain the case in
>>>>> this
>>>>> email with a bit more words. I am writing it, since I am confident at
>>>>> least it
>>>>> will be an interesting read.
>>>>>
>>>>> All of the three gists present a different implementation of a simple case
>>>>> with 4 very simple classes involved.
>>>>>
>>>>> There are two classes which render instances of types `int` and `float`
>>>>> (IntRenderer and FloatRenderer). Imagine similar classes that may render
>>>>> any other given type - user classes, a list, etc., but for simplification
>>>>> of the case I use only two classes. Each of those classes is instantiated
>>>>> with
>>>>> a variable and is called to render this variable into a string.
>>>>>
>>>>> There is an abstract base class (Renderer), which provides the common
>>>>> implementation for all the descendants and leaves the `__call__` to the be
>>>>> implemented by the concrete classes.
>>>>>
>>>>> The last, fourth, class is a dispatcher, which has the sole purpose to
>>>>> pick
>>>>> the right renderer, call it and return the result. We prefer many
>>>>> specialized
>>>>> classes instead of one big class that may render all types.
>>>>>
>>>>> The first gist uses composition to achieve that, which would be the
>>>>> usual way to do that. The dispatcher iterates, picks the right renderer,
>>>>> calls
>>>>> it and returns the value:
>>>>>
>>>>> https://gist.github.com/majorz/5342257
>>>>>
>>>>> Cooperative inheritance is however also a great pick for such a use case.
>>>>> In
>>>>> this type of implementation if a subclass cannot do the job (render), it
>>>>> will
>>>>> delegate the work with super() to the next class in the mro chain.
>>>>
>>>>
>>>> If you inherit from 20 or 100 classes, each attribute access becomes a
>>>> substantial linear search. I would forget inheritance and use a dict mapping
>>>> class of the object being rendered to the data needed to render it. In your
>>>> simple case, the dict would be {int:'INTEGER {}', float:'FLOAT {}'}.
>>>
>>> Which can easily be conbined with the "one render method per class"
>>> writing style you (Zahari) want with something just like:
>>> https://gist.github.com/jsbueno/5342460
>>> _______________________________________________
>>> Python-ideas mailing list
>>> Python-ideas at python.org
>>> http://mail.python.org/mailman/listinfo/python-ideas
More information about the Python-ideas
mailing list