On Sun, 25 Mar 2018 21:17:59 +1100, Chris Angelico wrote: > On Sun, Mar 25, 2018 at 8:37 PM, Jugurtha Hadjar > <jugurtha.had...@gmail.com> wrote: [...] >> I prefer to *feed* the child to the parent or vice versa. > > Congrats, this ranks on my list of "creative people who sound like > psycho murderers". Digital artists and cooks tend to rank fairly highly > on that list.
:-) >> class C1(object): >> def __init__(self): >> self.child = None >> class C2(object): >> def __init__(self, parent=None): >> self.parent = parent > > The trouble with this is that there's fully-constructed objects with no > parent-child relationships. Why should you have a two-step construction > process? Such a two-step construction process is normally called "dependency injection", and it's really useful. https://martinfowler.com/articles/injection.html Instead of class C2 controlling what its parent is: class C2: def __init__(self): self.parent = C1() the caller decides what parent to use. Provided the parent provides the same interface as C1, you can use any duck-type you like. The thing is, we use dependency injection in Python all the time. We just don't call it that! We normally write things like: class Spam: def __init__(self, queue=None): if queue is None: queue = Queue() self.queue = queue and so we get the best of both worlds: the ability to inject the queue we want when we need to, and the freedom to not bother when we don't. This is such second nature that we don't even think that what we're doing has a fancy OOP design pattern name that Java programmers stress over. And because we duck-type, we don't care if queue is a real queue, or just something that has all the queue methods we require. > It makes a LOT more sense to simply require a parent on > construction, rather than feeding one to the other in a > post-construction assignment. I tend to agree... but not everyone in the OOP world does. Quoting from Wikipedia: There are at least three ways an object can receive a reference to an external module: - constructor injection: the dependencies are provided through a class constructor. - setter injection: the client exposes a setter method that the injector uses to inject the dependency. - interface injection: the dependency provides an injector method that will inject the dependency into any client passed to it. https://en.wikipedia.org/wiki/Dependency_injection -- Steve -- https://mail.python.org/mailman/listinfo/python-list