Provenendo da Java, sto faticando un po 'a scaricare l'ereditarietà, le classi astratte, i metodi statici e concetti simili di programmazione OO in Python.Python 3: super() solleva TypeError in modo imprevisto
devo un'implementazione di una classe di albero di espressione, data (semplificato) di
# 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)
Il metodo to_expr()
funziona bene quando viene chiamato in casi di Leaf
, UnaryOpNode
e BinaryOpNode
, ma solleva un TypeError
quando viene chiamato su un istanza di VariadicOpNode
:
TypeError: super(type, obj): obj must be an instance or subtype of type
che cosa sto facendo di sbagliato in quella classe specifica che super()
non è improvvisamente wo rking?
In Java il metodo statico viene ereditato, quindi non avrei nemmeno bisogno della chiamata super, ma in Python non sembra essere il caso.
stai usando Python2 o 3? https://docs.python.org/2/library/functions.html#super – Jasper
@ Jasper Dal momento che sta usando 'super' senza argomenti sta usando python3.3 + credo. – Bakuriu
Off-topic: perché stai usando 'super()' in 'to_expr' per chiamare' bracket_complex'? Dovresti usare 'self', altrimenti rischi di introdurre problemi in sottoclassi che sovrascrivono' bracket_complex' –