Python 3: super() raises TypeError unexpectedly
从Java开始,我在Python中挣扎着继承继承、抽象类、静态方法和类似的OO编程概念。
我有一个表达式树类的实现,通过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # Generic node class class Node(ABC): @abstractmethod def to_expr(self): pass @staticmethod def bracket_complex(child): s = child.to_expr() return s if isinstance(child, Leaf) or isinstance(child, UnaryOpNode) else"(" + s +")" # Leaf class - used for values and variables class Leaf(Node): def __init__(self, val): self.val = val def to_expr(self): return str(self.val) # Unary operator node class UnaryOpNode(Node): def __init__(self, op, child): self.op = op self.child = child def to_expr(self): return str(self.op) + super().bracket_complex(self.child) # Binary operator node class BinaryOpNode(Node): def __init__(self, op, lchild, rchild): self.op = op self.lchild = lchild self.rchild = rchild def to_expr(self): return super().bracket_complex(self.lchild) +"" + str(self.op) +"" + super().bracket_complex(self.rchild) # Variadic operator node (arbitrary number of arguments) # Assumes commutative operator class VariadicOpNode(Node): def __init__(self, op, list_): self.op = op self.children = list_ def to_expr(self): return ("" + str(self.op) +"").join(super().bracket_complex(child) for child in self.children) |
当调用
1 | TypeError: super(type, obj): obj must be an instance or subtype of type |
在
在Java中,静态方法将继承,所以我甚至不需要超级调用,但在Python中,情况似乎并非如此。
您使用的
1 2 3 | def to_expr(self): bracket_complex = super().bracket_complex return ("" + str(self.op) +"").join(bracket_complex(child) for child in self.children) |
但是,由于静态方法在python中是"继承"的,如果没有在子类中重写它,那么可以通过
1 2 | def to_expr(self): return ("" + str(self.op) +"").join(self.bracket_complex(child) for child in self.children) |
实现细节是,如果没有提供参数,第一个参数应该是调用者帧的
因此,通常情况下,
回答你隐含的问题:
In Java the static method would get inherited so I wouldn't even need
the super call, but in Python this does not seem to be the case.
1 2 3 4 5 6 7 8 9 10 11 12 | class A: @staticmethod def a(): print('Hello') class B(A): def b(self): self.a() b = B() b.a() b.b() |
输出:
1 2 | Hello Hello |
请注意,您不能简单地写:
1 2 3 | class B(A): def b(self): a() |
python永远不会将简单名称解析为方法/静态方法;对于python
在python中,