Python super() - should be working but isn't?
As far as I can tell, and everything I've been finding online, this should work (but it doesn't, which is why I'm asking here ;) )
class Tigon(Crossbreeds, Predator, Lion):
def __init__(self):
super().__init__()
def printSize(self):
print("Huge")
Both "Crossbreeds" and "Predator" inherit from "Mammal", and "Lion" inherits from Predator. The compilation of those works fine. I'm working on Python 3.2, though I did also try the earlier:
Edit: Sorry, part of my post didn't come through for some reason.
I also tried:
class Tigon(Crossbreeds开发者_运维知识库, Predator, Lion):
def __init__(self):
super(Tigon, self).__init__()
def printSize(self):
print("Huge")
and both of them gave me:
class Tigon(Crossbreeds, Predator, Lion):
TypeError: Cannot create a consistent method resolution
order (MRO) for bases Predator, Mammal, Lion
Any suggestions?
Short answer: Don't inherit the same base class directly and indirectly, but inheriting directly after indirectly should work. So don't inherit Predator
or inherit it after Lion
.
Well, the C3 MRO seems to not be able to find any order consistent with all constraints. The constraints are that:
- each class must come before it's base classes
- and the base classes must come in the order they are listed.
You inherit Crossbreeds
, Predator
and Lion
in that order, so their methods must be called in that order. But since Lion
inherits Predator
, it's methods must be called before those of Predator
. Which is not possible, therefore it says it can't create consistent method resolution order.
Should be super().__init__(self)
.
Edited:
My apologize, you should put Lion
front:
class Tigon(Lion, Predator, Crossbreeds):
def __init__(self):
super().__init__()
If I correctly understood the inheritance model you described, this is how you should define the Tigon
class:
class Mammal(object):
def __init__(self):
super(Mammal, self).__init__()
class Crossbreeds(Mammal):
def __init__(self):
super(Crossbreeds, self).__init__()
class Predator(Mammal):
def __init__(self):
super(Predator, self).__init__()
class Lion(Predator):
def __init__(self):
super(Lion, self).__init__()
class Tigon(Lion, Crossbreeds, Predator):
def __init__(self):
super(Tigon, self).__init__()
t = Tigon()
this alternative is equivalent, since Lion is a Predator:
class Tigon(Lion, Crossbreeds):
def __init__(self):
super(Tigon, self).__init__()
Now here's a quick rule for this. Each class' constructor is called after base classes, but they must appear in the reverse order in the class definition. Also, classes that override methods defined in their parent class(es) must appear first in class definitions - this means that if you wanted to override a method of Predator in Lion, Lion should appear before Predator in the definition. The longer explanation for this is in Jan Hudec's answer.
精彩评论