
On Mon, 4 Apr 2022 at 08:09, malmiteria <martin.milon@ensc.fr> wrote:
Chris Angelico writes:
It's a very real problem in C++, because C++ has a completely different concept of multiple inheritance.
Then what's the solution to the diamond problem in python? in this example : ``` class HighGobelin: def scream(self): print("raAaaaAar")
class CorruptedGobelin(HighGobelin): def scream(self): print("my corrupted soul makes me wanna scream") super().scream()
class ProudGobelin(HighGobelin): def scream(self): print("I ... can't ... contain my scream!") super().scream()
class HalfBreed(ProudGobelin, CorrupteGobelin): def scream(self): if random.choices([True, False]): super(HalfBreed, self).scream() else: super(ProudGobelin, self).scream() ``` You want calls to ProudGobelin scream method to visit ProudGobelin, then HighGobelin Not ProudGobelin, then CorruptedGobelin, then HighGobelin.
If your solution is to revert back to the class.method syntax, you're again denying the proxy feature, the dependency injection use case, and the sideway specialisation (which to be fair is something we explicitely don't want here).
Mocking only HighGobelin through the dependency injection of super and MRO is not possible unless you can provide a solution for this case with super. class.method is then an incomplete solution.
Your problem is in the assumption that ProudGobelin and CorruptedGobelin will call HighGobelin's method. (Also, HalfBreed is one of the clear examples of typos in your code. Two, in fact. Maybe three, I'm not sure, and the third one I can't simply eyeball past, because it is genuinely ambiguous. Please test it.) So if you assume that, then why not write it? Don't use super().scream() here. Use HighGobelin.scream(self) instead. What do you intend for dependency injection to do with this scream method? What would make sense? You've already designed something that works differently. Don't forget that, in Python, the object *is what it is*, regardless of which class's method you're calling. You're not calling the "proud part of this object" or anything like that. You're simply calling a method on an object. If you don't want to follow the standard way of locating a method, use an explicit lookup instead. ChrisA