Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think multiple inheritance will always scare me. What order do the superclass inits run in? What happens if they do conflicting things? What if some superclasses call super().__init__ and others don't?

No thanks, I'll suffer through reading a few additional lines of:

class SomeBusinessyThing:

  def __init__(self, util, other_util):
    self._util = util
    self._other_util = other_util

  @classmethod
  def create(cls):
    return cls(util_module.Util(), other_module.Other())

  def calculate(self):
    source = self_other_util.get_source()
    return self._util.get_stuff(source)
vs

class SomeBusinessyThing(Utils, Other):

  def __init__(self, \*kwargs):
    # What does this do? No one knows
    super().__init__(self, \*kwargs)

  def calculate(self):
    source = self.get_source()
    return self.get_stuff(source)


Meh, that's just the standard composition vs inheritance dichotomy. In reality, those two concepts are orthogonal, and you can use one, the other, and both, as suitable to the situation.

Using multiple inheritance to implement certain common functionality, using mixin classes, is possible in Python; it's another powerful tool in the arsenal, but doesn't mean that you have to use it.

Inheritance works best to denote "is-a" relationships, i.e. for defining subtypes, especially when using type annotations and checks. Sometimes - albeit very rarely - you need a class that belongs to two separate type hierarchies; multiple inheritance comes very handy in those cases.


One case where I (ab)used this in R was to add an abstract class called Timed that measured the time the inner function took.

I guess I'd probably use a decorator in Python but this was R and I was on an S4 buzz back then so I took the approach above.


I don't think he is unaware of any of that. His point was that multiple inheritance involves enough fiddly surprising behaviour that it's best avoided - you are better off manually delegating to distinct member variables, then it is clear what is happening even if it is a bit more tedious.

(Btw that's the only way to implement inheritance in Rust, even single inheritance.)


> multiple inheritance involves enough fiddly surprising behaviour

In which way? MRO is very well defined.

> manually delegating to distinct member variables

Again, this is composition, which has nothing to do with inheritance. If you need to define a subtype, inheritance is most straightforward.


The Method Resolution Order (MRO) is firm and documented. It's just not something anyone keeps in mind unless you use multiple inheritance a lot.

Conflicts are determined by the MRO. If some classes don't call super(), then they won't call super --> classes further down the MRO won't be called and won't be initialized.

The choice isn't: multiple inheritance or a couple lines. In the right situation, multiple inheritance could save hundreds of lines and condense a complicated mechanism into a simplistic one. Used flippantly, they can be a nightmare -- but that's true of all programming paradigms.


I won’t argue with “keep things simple” but if you’re ever forced to work with multiple inheritance in Python try inspecting:

  SomeBusinessyThing.__mro__
https://docs.python.org/3/library/stdtypes.html#class.__mro_...


Agree, core feature of Python is to be readable and familiar. While I enjoy reading more advanced deep dives in language features, at the point you’re being crafty to flex, it’s likely bad idea; aka if next person reading your code mostly will have no clue what it’s doing, it’s likely a bad idea to do.

Wish there was a way to visualize or rate how average code is - especially two separate versions covering same concept; hence my other comments on resources to quantify usage patterns.


This is "explicit is better tha implicit".

I would think that Inwoukd hate the above code but actually I appreciate it and prefer it. It's great.


Over thinking it, I think this is probably the "right" solution to multiple inheritance where there are conflicting attributes.

I suspect it is a hard pre-commit check but you would want to only inherit from classes with no conflict- then if there are it is down to this approach (!)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: