Re: Composition instead of inheritance

2011-05-02 Thread Alan Meyer

On 4/28/2011 1:15 PM, Ethan Furman wrote:

For anybody interested in composition instead of multiple inheritance, I
have posted this recipe on ActiveState (for python 2.6/7, not 3.x):

http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/


Comments welcome!

~Ethan~


That looks pretty clever.  I tried adding this method to Spam:

def test_eggs_02(self):
print('testing eggs_02 from spam')

and it did just what we wanted.

I'm going to have to study this one.

Thanks.

Alan
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-29 Thread Jean-Michel Pichavant

Ben Finney wrote:

Ethan Furman et...@stoneleaf.us writes:

  

Carl Banks wrote:


That's not what we mean by composition. Composition is when one
object calls upon another object that it owns to implement some of
its behavior. Often used to model a part/whole relationship, hence
the name.
  

Hmmm. Okay -- any ideas for a better term? Something that describes
taking different source classes and fusing them into a new whole,
possibly using single-inheritance... Frankenstein, maybe? ;)



(Remember that Frankenstein was not the monster, but the scientist.)

“Hybrid”?

  

Actualy this story is about the villagers being the monsters :o)

JM
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-29 Thread Ethan Furman

James Mills wrote:

On Fri, Apr 29, 2011 at 11:43 AM, Ethan Furman et...@stoneleaf.us wrote:

Hmmm. Okay -- any ideas for a better term?  Something that describes taking
different source classes and fusing them into a new whole, possibly using
single-inheritance... Frankenstein, maybe?  ;)


I'd have to say that this is typical of MixIns


Yes, but it's designed to be used when Mixins fail because of MI issues 
(see my reply to Carl for an example).


Maybe Integrate?

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-29 Thread Carl Banks
On Thursday, April 28, 2011 6:43:35 PM UTC-7, Ethan Furman wrote:
 Carl Banks wrote:
  The sorts of class that this decorator will work for are probably not
   the ones that are going to have problems cooperating in the first place.
   So you might as well just use inheritance; that way people trying to read
   the code will have a common, well-known Python construct rather than a
   custom decorator to understand.
 
  From thread 'python and super' on Python-Dev:
 Ricardo Kirkner wrote:
   I'll give you the example I came upon:
  
   I have a TestCase class, which inherits from both Django's TestCase
   and from some custom TestCases that act as mixin classes. So I have
   something like
  
   class MyTestCase(TestCase, Mixin1, Mixin2):
  ...
  
   now django's TestCase class inherits from unittest2.TestCase, which we
   found was not calling super.
 
 This is the type of situation the decorator was written for (although 
 it's too simplistic to handle that exact case, as Ricardo goes on to say 
 he has a setUp in each mixin that needs to be called -- it works fine 
 though if you are not adding duplicate names).

The problem is that he was doing mixins wrong.  Way wrong.

Here is my advice on mixins:

Mixins should almost always be listed first in the bases.  (The only exception 
is to work around a technicality.  Otherwise mixins go first.)

If a mixin defines __init__, it should always accept self, *args and **kwargs 
(and no other arguments), and pass those on to super().__init__.  Same deal 
with any other function that different sister classes might define in varied 
ways (such as __call__).

A mixin should not accept arguments in __init__.  Instead, it should burden the 
derived class to accept arguments on its behalf, and set attributes before 
calling super().__init__, which the mixin can access.

If you insist on a mixin that accepts arguments in __init__, then it should 
should pop them off kwargs.  Avoid using positional arguments, and never use 
named arguments.  Always go through args and kwargs.

If mixins follow these rules, they'll be reasonably safe to use on a variety of 
classes.  (Maybe even safe enough to use in Django classes.)


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-29 Thread Ethan Furman

Carl Banks wrote:

Here is my advice on mixins:


[snip]

Cool.  Thanks!

~Ethan
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-29 Thread Ian Kelly
On Fri, Apr 29, 2011 at 3:09 PM, Carl Banks pavlovevide...@gmail.com wrote:
 Here is my advice on mixins:

 Mixins should almost always be listed first in the bases.  (The only 
 exception is to work around a technicality.  Otherwise mixins go first.)

 If a mixin defines __init__, it should always accept self, *args and **kwargs 
 (and no other arguments), and pass those on to super().__init__.  Same deal 
 with any other function that different sister classes might define in varied 
 ways (such as __call__).

Really, *any* class that uses super().__init__ should take its
arguments and pass them along in this manner.  This applies to your
base classes as well as your mixins.  It's okay to take keyword
arguments as well, but you have to be careful to pass them on exactly
as you received them.  Reason being that you can't pragmatically
predict which __init__ method will be invoked next by the super call,
which means that you can't predict which arguments will be needed for
that call, so you just have to pass all of them along.

 A mixin should not accept arguments in __init__.  Instead, it should burden 
 the derived class to accept arguments on its behalf, and set attributes 
 before calling super().__init__, which the mixin can access.

Ugh.  This breaks encapsulation, since if I ever need to add an
optional argument, I have to add handling for that argument to every
derived class that uses that mixin.  The mixin should be able to
accept new optional arguments without the derived classes needing to
know about them.

 If you insist on a mixin that accepts arguments in __init__, then it should 
 should pop them off kwargs.  Avoid using positional arguments, and never use 
 named arguments.  Always go through args and kwargs.

Theoretically this would break if you had two mixins accepting the
same argument, but I can't think of an actual case where that might
happen.

Cheers,
Ian
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-29 Thread Ethan Furman

Ian Kelly wrote:

On Thu, Apr 28, 2011 at 11:15 AM, Ethan Furman et...@stoneleaf.us wrote:

For anybody interested in composition instead of multiple inheritance, I
have posted this recipe on ActiveState (for python 2.6/7, not 3.x):

http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/

Comments welcome!


On line 14, is it intentional that attributes whose values happen to
be false are not considered as conflicts?


Nope, not intentional at all!  I'll fix that...



On line 31, this code:

thing = getattr(thing, '__func__', None) or thing

could be simplified to this:

thing = getattr(thing, '__func__', thing)


I'll fix that, too.


Thanks!
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-29 Thread Carl Banks
On Friday, April 29, 2011 2:44:56 PM UTC-7, Ian wrote:
 On Fri, Apr 29, 2011 at 3:09 PM, Carl Banks 
  wrote:
  Here is my advice on mixins:
 
  Mixins should almost always be listed first in the bases.  (The only 
  exception is to work around a technicality.  Otherwise mixins go first.)
 
  If a mixin defines __init__, it should always accept self, *args and 
  **kwargs (and no other arguments), and pass those on to super().__init__.  
  Same deal with any other function that different sister classes might 
  define in varied ways (such as __call__).
 
 Really, *any* class that uses super().__init__ should take its
 arguments and pass them along in this manner.

If you are programming defensively for any possible scenario, you might try 
this (and you'd still fail).

In the real world, certain classes might have more or less probability to be 
used in a multiple inheritance situations, and programmer needs to weigh the 
probability of that versus the loss of readability.  For me, except when I'm 
designing a class specifically to participate in MI (such as a mixin), 
readability wins.

[snip]
  A mixin should not accept arguments in __init__.  Instead, it should burden 
  the derived class to accept arguments on its behalf, and set attributes 
  before calling super().__init__, which the mixin can access.
 
 Ugh.  This breaks encapsulation, since if I ever need to add an
 optional argument, I have to add handling for that argument to every
 derived class that uses that mixin.  The mixin should be able to
 accept new optional arguments without the derived classes needing to
 know about them.

Well, encapsulation means nothing to me; if it did I'd be using Java.

If you merely mean DRY, then I'd say this doesn't necessarily add to it.  The 
derived class has a responsibility one way or another to get the mixin whatever 
initializers it needs.  Whether it does that with __init__ args or through 
attributes it still has to do it.  Since attributes are more versatile than 
arguments, and since it's messy to use arguments in MI situations, using 
attributes is the superior method. 


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-29 Thread Ian Kelly
On Fri, Apr 29, 2011 at 5:54 PM, Carl Banks pavlovevide...@gmail.com wrote:
 Really, *any* class that uses super().__init__ should take its
 arguments and pass them along in this manner.

 If you are programming defensively for any possible scenario, you might try 
 this (and you'd still fail).

 In the real world, certain classes might have more or less probability to be 
 used in a multiple inheritance situations, and programmer needs to weigh the 
 probability of that versus the loss of readability.  For me, except when I'm 
 designing a class specifically to participate in MI (such as a mixin), 
 readability wins.

Agreed.  Actually, my preferred solution is to not use super at all.
It's so rarely needed (i.e. diamond inheritance situations) that it's
usually not worth it to jump through the hoops it creates, so I prefer
to call the base class methods explicitly.

For pure base-class + mixin design, you should not have any diamond
inheritance situations, so super should not really be necessary.

 If you merely mean DRY, then I'd say this doesn't necessarily add to it.  The 
 derived class has a responsibility one way or another to get the mixin 
 whatever initializers it needs.

I mean the difference in terms of maintenance between this:

class Derived1(Mixin1, Base):
def __init__(self, mixin_arg1, mixin_arg2, *args, **kwargs):
self.mixin_arg1 = mixin_arg1
self.mixin_arg2 = mixin_arg2
super(Derived, self).__init__(*args, **kwargs)

and simply doing this:

class Derived2(Mixin2, Base):
def __init__(self, *args, **kwargs):
super(Derived, self).__init__(*args, **kwargs)

In both cases we are passing the arguments in to the mixin.  In the
former case, if we later decide to add mixin_arg3, then we have to
also add it to the Derived1.__init__ signature and then add a line to
set the attribute.  In the latter case, adding mixin_arg3 has no
effect on the Derived2 initializer at all, because it passes through
transparently in the kwargs.

Cheers,
Ian
-- 
http://mail.python.org/mailman/listinfo/python-list


Composition instead of inheritance

2011-04-28 Thread Ethan Furman
For anybody interested in composition instead of multiple inheritance, I 
have posted this recipe on ActiveState (for python 2.6/7, not 3.x):


http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/

Comments welcome!

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Eric Snow
On Thu, Apr 28, 2011 at 11:15 AM, Ethan Furman et...@stoneleaf.us wrote:

 For anybody interested in composition instead of multiple inheritance, I
 have posted this recipe on ActiveState (for python 2.6/7, not 3.x):


 http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/

 Comments welcome!

 ~Ethan~
 --
 http://mail.python.org/mailman/listinfo/python-list


That's cool.  And if Spam and Eggs were abstract base classes you could
register TestAll to them.  Granted, that is not so applicable in your
example.   But generally that would help bridge the inheritance gap for
isinstance cases.

-eric

p.s. I would have commented on the recipe but could not log in...
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Jean-Michel Pichavant

Ethan Furman wrote:
For anybody interested in composition instead of multiple inheritance, 
I have posted this recipe on ActiveState (for python 2.6/7, not 3.x):


http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/ 



Comments welcome!

~Ethan~

Sounds great. But I fear that would completely fool any linter.

JM
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Ben Finney
Ethan Furman et...@stoneleaf.us writes:

 For anybody interested in composition instead of multiple inheritance,
 I have posted this recipe on ActiveState (for python 2.6/7, not 3.x):

 http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/

 Comments welcome!

It doesn't look like composition at all, though. I understand
composition to be the setting of attributes on a class or instance; that
recipe doesn't show it very well IMO.

-- 
 \ “[The RIAA] have the patience to keep stomping. They're playing |
  `\ whack-a-mole with an infinite supply of tokens.” —kennon, |
_o__) http://kuro5hin.org/ |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Carl Banks
On Thursday, April 28, 2011 10:15:02 AM UTC-7, Ethan Furman wrote:
 For anybody interested in composition instead of multiple inheritance, I 
 have posted this recipe on ActiveState (for python 2.6/7, not 3.x):
 
 http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/
 
 Comments welcome!

That's not what we mean by composition.  Composition is when one object calls 
upon another object that it owns to implement some of its behavior.  Often used 
to model a part/whole relationship, hence the name.

The sorts of class that this decorator will work for are probably not the ones 
that are going to have problems cooperating in the first place.  So you might 
as well just use inheritance; that way people trying to read the code will have 
a common, well-known Python construct rather than a custom decorator to 
understand.

If you want to enforce no duplication of attributes you can do that, such as 
with this untested metaclass:

class MakeSureNoBasesHaveTheSameClassAttributesMetaclass(type):
def __new__(metatype,name,bases,dct):
u = collections.Counter()
for base in bases:
for key in base.__dict__.keys():
u[key] += 1
for key in dct.keys():
u[key] += 1
if any(u[key]  1 for key in u.keys()):
raise TypeError(base classes and this class share some class 
attributes)
return type.__new__(metatype,name,bases,dct)
 

Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Ethan Furman

Carl Banks wrote:

That's not what we mean by composition.  Composition is when one object

 calls upon another object that it owns to implement some of its behavior.
 Often used to model a part/whole relationship, hence the name.

Hmmm. Okay -- any ideas for a better term?  Something that describes 
taking different source classes and fusing them into a new whole, 
possibly using single-inheritance... Frankenstein, maybe?  ;)




The sorts of class that this decorator will work for are probably not

 the ones that are going to have problems cooperating in the first place.
 So you might as well just use inheritance; that way people trying to read
 the code will have a common, well-known Python construct rather than a
 custom decorator to understand.

From thread 'python and super' on Python-Dev:
Ricardo Kirkner wrote:
 I'll give you the example I came upon:

 I have a TestCase class, which inherits from both Django's TestCase
 and from some custom TestCases that act as mixin classes. So I have
 something like

 class MyTestCase(TestCase, Mixin1, Mixin2):
...

 now django's TestCase class inherits from unittest2.TestCase, which we
 found was not calling super.

This is the type of situation the decorator was written for (although 
it's too simplistic to handle that exact case, as Ricardo goes on to say 
he has a setUp in each mixin that needs to be called -- it works fine 
though if you are not adding duplicate names).


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread MRAB

On 29/04/2011 02:43, Ethan Furman wrote:

Carl Banks wrote:

That's not what we mean by composition. Composition is when one object

  calls upon another object that it owns to implement some of its
behavior.
  Often used to model a part/whole relationship, hence the name.

Hmmm. Okay -- any ideas for a better term? Something that describes
taking different source classes and fusing them into a new whole,
possibly using single-inheritance... Frankenstein, maybe? ;)


[snip]
Fusing/fusion? Compounding?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Steven D'Aprano
On Thu, 28 Apr 2011 15:35:47 -0700, Carl Banks wrote:

 On Thursday, April 28, 2011 10:15:02 AM UTC-7, Ethan Furman wrote:
 For anybody interested in composition instead of multiple inheritance,
 I have posted this recipe on ActiveState (for python 2.6/7, not 3.x):
 
 http://code.activestate.com/recipes/577658-composition-of-classes-
instead-of-multiple-inherit/
 
 Comments welcome!
 
 That's not what we mean by composition.  Composition is when one object
 calls upon another object that it owns to implement some of its
 behavior.

I thought that was delegation. As in, when one object delegates some or 
all of it's behaviour to another object:

http://code.activestate.com/recipes/52295


 Often used to model a part/whole relationship, hence the name.

In mathematics, composition means to make a function by applying a 
function to the output of another. E.g.:

f o g(x) is equivalent to f(g(x))

(Strictly speaking, the o in the f o g should be a little circle rather 
than lowercase O.)



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread James Mills
On Fri, Apr 29, 2011 at 11:43 AM, Ethan Furman et...@stoneleaf.us wrote:
 Hmmm. Okay -- any ideas for a better term?  Something that describes taking
 different source classes and fusing them into a new whole, possibly using
 single-inheritance... Frankenstein, maybe?  ;)

I'd have to say that this is typical of MixIns

cheers
James

-- 
-- James Mills
--
-- Problems are solved by method
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Ben Finney
Ethan Furman et...@stoneleaf.us writes:

 Carl Banks wrote:
  That's not what we mean by composition. Composition is when one
  object calls upon another object that it owns to implement some of
  its behavior. Often used to model a part/whole relationship, hence
  the name.

 Hmmm. Okay -- any ideas for a better term? Something that describes
 taking different source classes and fusing them into a new whole,
 possibly using single-inheritance... Frankenstein, maybe? ;)

(Remember that Frankenstein was not the monster, but the scientist.)

“Hybrid”?

-- 
 \  “If sharing a thing in no way diminishes it, it is not rightly |
  `\  owned if it is not shared.” —Augustine of Hippo (354–430 CE) |
_o__)  |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Ben Finney
Steven D'Aprano steve+comp.lang.pyt...@pearwood.info writes:

 On Thu, 28 Apr 2011 15:35:47 -0700, Carl Banks wrote:

  That's not what we mean by composition. Composition is when one
  object calls upon another object that it owns to implement some of
  its behavior.

 I thought that was delegation. As in, when one object delegates some or 
 all of it's behaviour to another object:

 http://code.activestate.com/recipes/52295

The difference being that, with delegation, the object being called is
unrelated to this one. With composition, the object being called is not
wholly separate, but is instead an attribute on the current object.

The “another object that it owns” was, I presume, meant to communicate
this “an object which is an attribute of the current one” relationship.

 In mathematics, composition means to make a function by applying a 
 function to the output of another.

The term “composition” in the programming sense comes from OO design,
not functional nor mathematical terminology.

-- 
 \  “I don't like country music, but I don't mean to denigrate |
  `\  those who do. And for the people who like country music, |
_o__)denigrate means ‘put down’.” —Bob Newhart |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Dan Stromberg
On Thu, Apr 28, 2011 at 3:35 PM, Carl Banks pavlovevide...@gmail.com wrote:
 On Thursday, April 28, 2011 10:15:02 AM UTC-7, Ethan Furman wrote:
 For anybody interested in composition instead of multiple inheritance, I
 have posted this recipe on ActiveState (for python 2.6/7, not 3.x):

 http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/

 Comments welcome!

 That's not what we mean by composition.  Composition is when one object calls 
 upon another object that it owns to implement some of its behavior.  Often 
 used to model a part/whole relationship, hence the name.

It's a pretty old idea, that seems to be getting revived in a big way
all of a sudden.  Perhaps the Java people just rediscovered it?

In a Software Engineering class using Ada, the teacher called it
Structural Inclusion, and of course it was an important concept in
Ada, because Ada had no inheritance.  This was in 1989-1990.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Ben Finney
Dan Stromberg drsali...@gmail.com writes:

 On Thu, Apr 28, 2011 at 3:35 PM, Carl Banks pavlovevide...@gmail.com wrote:
  That's not what we mean by composition.  Composition is when one
  object calls upon another object that it owns to implement some of
  its behavior.  Often used to model a part/whole relationship, hence
  the name.

 It's a pretty old idea, that seems to be getting revived in a big way
 all of a sudden. Perhaps the Java people just rediscovered it?

I think it's more that people keep re-discovering how irredeemably messy
multiple inheritance is, and finding that object composition is better
in most cases :-)

-- 
 \  “There's a fine line between fishing and standing on the shore |
  `\looking like an idiot.” —Steven Wright |
_o__)  |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread Ian Kelly
On Thu, Apr 28, 2011 at 11:15 AM, Ethan Furman et...@stoneleaf.us wrote:
 For anybody interested in composition instead of multiple inheritance, I
 have posted this recipe on ActiveState (for python 2.6/7, not 3.x):

 http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/

 Comments welcome!

On line 14, is it intentional that attributes whose values happen to
be false are not considered as conflicts?

On line 31, this code:

thing = getattr(thing, '__func__', None) or thing

could be simplified to this:

thing = getattr(thing, '__func__', thing)

Cheers,
Ian
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Composition instead of inheritance

2011-04-28 Thread John Nagle

On 4/28/2011 3:35 PM, Carl Banks wrote:

On Thursday, April 28, 2011 10:15:02 AM UTC-7, Ethan Furman wrote:

For anybody interested in composition instead of multiple
inheritance, I have posted this recipe on ActiveState (for python
2.6/7, not 3.x):

http://code.activestate.com/recipes/577658-composition-of-classes-instead-of-multiple-inherit/




Comments welcome!


That's not what we mean by composition.  Composition is when one
object calls upon another object that it owns to implement some of
its behavior.  Often used to model a part/whole relationship, hence
the name.


The distinction isn't that strong in Python, where an object
can't be part of another object.  Object fields are references, not
the objects themselves.

In C++, you really can have an object as a field of an enclosing
object.  The inner object's destructor will be called first.
Destructors and ownership tend not to be too important in Python,
because storage management is automatic.

John Nagle
--
http://mail.python.org/mailman/listinfo/python-list