[Python-ideas] Composition over Inheritance

Brendan Barnwell brenbarn at brenbarn.net
Sat Oct 28 22:25:12 EDT 2017

On 2017-10-28 19:13, Soni L. wrote:
> Hmm thinking about it some more, this whole "magic()" thing is still bad.
> Replace class Car with:
> class Car:
>     pass
> # or something like that
> and use it as:
> car = Car()
> car[Engine] = GasEngine() # please use the actual type instead of a
> stringy type for this.
> car[Engine].kickstart() # kickstart gets the car as second argument.
> And to have all cars have engines, you'd do:
> class Car:
>     def __init__(self, ???):
>       self[Engine] = GasEngine()
> car = Car()
> car[Engine].kickstart() # kickstart gets the car as second argument.
> And if you can't do that, then you can't yet do what I'm proposing, and
> thus the proposal makes sense, even if it still needs some refining...

	As near as I can tell you can indeed do that, although it's still not 
clear to me why you'd want to.  You can give Car a __getitem__ that 
on-the-fly generates an Engine object that knows which Car it is 
attached to, and then you can make Engine.kickstart a descriptor that 
knows which Engine it is attached to, and from that can figure out which 
Car it is attached to.

	But why?  Why do you want to use this particular syntax to do these 
things?  You haven't explained what semantics you're attaching to the 
[brackets] as opposed to the .attribute notation.  Also, why do you want 
the car to be the second argument?  What if the components are more 
deeply nested?  Are you going to pass every parent component as a 
separate argument?  Why not just have the call be made on an object that 
has the car available as an attribute (so that inside kickstart() you 
can access self.car or something)?

	The pandas library, for instance, makes heavy use of descriptors along 
these lines.  A DataFrame object has attributes called .loc and .iloc 
that you use to do different kinds of indexing with things like 
my_data_frame.loc['this':'that'] .  This appears conceptually similar to 
what you're describing here.  But it's hard to tell, because you still 
haven't given a clear, direct example of how you would use what you're 
proposed to actually accomplish some task.

Brendan Barnwell
"Do not follow where the path may lead.  Go, instead, where there is no 
path, and leave a trail."
    --author unknown

More information about the Python-ideas mailing list