Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #110902 > unrolled thread

super and mix-in class: how exactly is the search order altered?

Started by"Veek. M" <vek.m1234@gmail.com>
First post2016-07-01 19:54 +0530
Last post2016-07-03 20:22 +0530
Articles 3 — 2 participants

Back to article view | Back to comp.lang.python


Contents

  super and mix-in class: how exactly is the search order altered? "Veek. M" <vek.m1234@gmail.com> - 2016-07-01 19:54 +0530
    Re: super and mix-in class: how exactly is the search order altered? dieter <dieter@handshake.de> - 2016-07-02 09:30 +0200
      Re: super and mix-in class: how exactly is the search order altered? "Veek. M" <vek.m1234@gmail.com> - 2016-07-03 20:22 +0530

#110902 — super and mix-in class: how exactly is the search order altered?

From"Veek. M" <vek.m1234@gmail.com>
Date2016-07-01 19:54 +0530
Subjectsuper and mix-in class: how exactly is the search order altered?
Message-ID<nl5ufm$4a8$1@dont-email.me>
I had posted this on StackOverflow - it's an excellent example of why SO 
sucks (don't want that happening here so please read carefully):

http://stackoverflow.com/questions/38145818/super-and-mix-in-class-how-exactly-is-the-search-order-altered?noredirect=1#comment63722336_38145818


I'm reading this article: 
https://rhettinger.wordpress.com/2011/05/26/super-considered-super/

He's trying to explain the purpose of a 'mix-in class' and he says

    We did not alter the source code for LoggingDict. Instead we built a 
subclass whose only logic is to compose two existing classes and control 
their search order.

class LoggingOD(LoggingDict, collections.OrderedDict):
    pass

My question is this: in the above article context, is he talking about 
the LoggingDict's search order that is being manipulated? Or he is 
talking about manipulating the LoggingOD search order?

He says very clearly "not alter the source code for LoggingDict" so 
clearly he means that somehow, magically - the search order for 
super().__setitem__ in

class LoggingDict(dict):
    def __setitem__(self, key, value):
        logging.info('Settingto %r' % (key, value))
        super().__setitem__(key, value)

is being altered/influenced, but how? Could someone clarify what exactly 
is going on here? Far as I can make of it, the tree looks like this: 
http://i.stack.imgur.com/3foOB.jpg

Here's the code:
import collections

class LoggingDict(dict):
    def __setitem__(self, key, value):
        logging.info('Settingto %r' % (key, value))
        super().__setitem__(key, value)

class LoggingOD(LoggingDict, collections.OrderedDict):
    pass

x = LoggingDict()
print LoggingDict.__mro__
print LoggingOD.__mro__

as you can see.. 

selfstudy@deathstar:~$ python 29.mro.py 
(<class '__main__.LoggingDict'>, <type 'dict'>, <type 'object'>)
(<class '__main__.LoggingOD'>, <class '__main__.LoggingDict'>, <class 
'collections.OrderedDict'>, <type 'dict'>, <type 'object'>)
selfstudy@deathstar:~$ 

[toc] | [next] | [standalone]


#110948

Fromdieter <dieter@handshake.de>
Date2016-07-02 09:30 +0200
Message-ID<mailman.19.1467444623.2295.python-list@python.org>
In reply to#110902
"Veek. M" <vek.m1234@gmail.com> writes:
> ...
> I'm reading this article: 
> https://rhettinger.wordpress.com/2011/05/26/super-considered-super/
>
> He's trying to explain the purpose of a 'mix-in class' and he says
>
>     We did not alter the source code for LoggingDict. Instead we built a 
> subclass whose only logic is to compose two existing classes and control 
> their search order.
>
> class LoggingOD(LoggingDict, collections.OrderedDict):
>     pass
>
> My question is this: in the above article context, is he talking about 
> the LoggingDict's search order that is being manipulated? Or he is 
> talking about manipulating the LoggingOD search order?

Likely, his language has been a bit sloppy.

Likely, his setup is as follows:

 * He has an existing class ("collections.OrderDict")
   which the base functionality he needs

 * He has an additional requirement (over that of "collections.OrderDict")
   -- logging modifications

 * He wants to implement his requirements (the base ones and the
   the additional one) without modifying the existing class in any way

 * His idea to implement the additional requirement is to define
   a derived class ("LoggingOD") and lets its modifying methods perform
   the logging and then call the corresponding methods of the
   base class.

 * He recognizes that this logging feature might be interesting
   not only for "collections.OrderDict" but also for other
   dictionary like base classes.
   Therefore, instead of implementing it directly in
   "LoggingOD", he implements it in the mixin class "LoggingDict".

 * Because "LoggingDict" was explicitely designed to be used
   as mixin class to enhance a base class, it knows that
   some methods ("__setitem__") of the base class need to be called
   in its own implementation of the corresponding method.

 * The integrator (the one combining "LoggingDict" with the base
   class) must ensure (by an appropriate inheritance order)
   that the combining class ("LoggingOD" in the example)
   calls the "LoggingDict"'s methods (which know about that of the
   base class) rather than the base class's methods (which do not
   know about the mixin class's methods).

   Therefore, he uses the inheritance order "LoggingDict" followed
   by the base class (and not vice versa).


Python clearly defines in what order attributes of an object
and of the construct "super(<base>,<obj>)" are looked up.

The essential concept is the so called "MRO" ("method resolution order")
(in fact, it is an attribute resolution order).

In simple cases (no common base classes), the MRO of
a definition "class C(B_1, ..., B_n): ..."
is defined by a left to right lookup: i.e. first in "C", then "B_1",
then "B_2", ...

The rules are a bit more complicated when the "B_i" have a (or more)
common base classes.

[toc] | [prev] | [next] | [standalone]


#110998

From"Veek. M" <vek.m1234@gmail.com>
Date2016-07-03 20:22 +0530
Message-ID<nlb8rs$afg$2@dont-email.me>
In reply to#110948
dieter wrote:

> "Veek. M" <vek.m1234@gmail.com> writes:
>> ...
>> I'm reading this article:
>> https://rhettinger.wordpress.com/2011/05/26/super-considered-super/
>>
>> He's trying to explain the purpose of a 'mix-in class' and he says
>>
>>     We did not alter the source code for LoggingDict. Instead we
>>     built a
>> subclass whose only logic is to compose two existing classes and
>> control their search order.
>>
>> class LoggingOD(LoggingDict, collections.OrderedDict):
>>     pass
>>
>> My question is this: in the above article context, is he talking
>> about the LoggingDict's search order that is being manipulated? Or he
>> is talking about manipulating the LoggingOD search order?
> 
> Likely, his language has been a bit sloppy.
> 
> Likely, his setup is as follows:
> 
>  * He has an existing class ("collections.OrderDict")
>    which the base functionality he needs
> 
>  * He has an additional requirement (over that of
>  "collections.OrderDict")
>    -- logging modifications
> 
>  * He wants to implement his requirements (the base ones and the
>    the additional one) without modifying the existing class in any way
> 
>  * His idea to implement the additional requirement is to define
>    a derived class ("LoggingOD") and lets its modifying methods
>    perform the logging and then call the corresponding methods of the
>    base class.
> 
>  * He recognizes that this logging feature might be interesting
>    not only for "collections.OrderDict" but also for other
>    dictionary like base classes.
>    Therefore, instead of implementing it directly in
>    "LoggingOD", he implements it in the mixin class "LoggingDict".
> 
>  * Because "LoggingDict" was explicitely designed to be used
>    as mixin class to enhance a base class, it knows that
>    some methods ("__setitem__") of the base class need to be called
>    in its own implementation of the corresponding method.
> 
>  * The integrator (the one combining "LoggingDict" with the base
>    class) must ensure (by an appropriate inheritance order)
>    that the combining class ("LoggingOD" in the example)
>    calls the "LoggingDict"'s methods (which know about that of the
>    base class) rather than the base class's methods (which do not
>    know about the mixin class's methods).
> 
>    Therefore, he uses the inheritance order "LoggingDict" followed
>    by the base class (and not vice versa).
> 
> 
> Python clearly defines in what order attributes of an object
> and of the construct "super(<base>,<obj>)" are looked up.
> 
> The essential concept is the so called "MRO" ("method resolution
> order") (in fact, it is an attribute resolution order).
> 
> In simple cases (no common base classes), the MRO of
> a definition "class C(B_1, ..., B_n): ..."
> is defined by a left to right lookup: i.e. first in "C", then "B_1",
> then "B_2", ...
> 
> The rules are a bit more complicated when the "B_i" have a (or more)
> common base classes.

Hey Dieter, I'll need some time to read this and get back on it - hope 
that's okay. But yeah, I think he's explaining it badly and extremely 
misleading (imho).

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web