Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #110902 > unrolled thread
| Started by | "Veek. M" <vek.m1234@gmail.com> |
|---|---|
| First post | 2016-07-01 19:54 +0530 |
| Last post | 2016-07-03 20:22 +0530 |
| Articles | 3 — 2 participants |
Back to article view | Back to comp.lang.python
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
| From | "Veek. M" <vek.m1234@gmail.com> |
|---|---|
| Date | 2016-07-01 19:54 +0530 |
| Subject | super 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]
| From | dieter <dieter@handshake.de> |
|---|---|
| Date | 2016-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]
| From | "Veek. M" <vek.m1234@gmail.com> |
|---|---|
| Date | 2016-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