来自Java,我正在努力学习Python中的继承、抽象类、静态方法和类似的OO编程概念。在
我有一个表达式树类的实现,由
# 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)
方法to_expr()
在对Leaf
、UnaryOpNode
和{VariadicOpNode
的实例调用时会引发一个TypeError
:
在那个突然失效的特定类中,我做错了什么?在
在Java中,静态方法将被继承,因此我甚至不需要超级调用,但在Python中,情况似乎并非如此。在
您在生成器表达式中使用没有参数的
super()
。super()
很神奇-它依赖于调用方帧中的信息。由于生成器表达式创建了一个附加函数,因此没有参数的super()
在那里不起作用。但是,由于超类不太可能在方法的执行过程中更改,因此可以将其移出生成器表达式-这也可以加快速度:但是,由于静态方法在Python中是“继承”的,所以可以通过
^{pr2}$self
调用超级方法,前提是没有在子类中重写它。因此,在这个简单的例子中,你可以写下:实现细节是,如果没有提供参数,第一个参数应该是调用者帧的
__class__
单元格中的值,第二个参数应该是给调用者函数的第一个参数。通常,在错误的位置使用super
时,只会得到一个SystemError
,但是生成器表达式被包装在一个隐式生成器函数中,该函数会创建另一个调用帧。不幸的是,这个函数得到一个参数,这导致super()
抱怨这个异常。在因此,通常}。在
super()
将作为第一个参数传递给Foo
,但在生成器表达式中,传递了一个生成器对象,因此很明显需要引发{回答你暗示的问题:
staticmethod
s是继承的:输出:
^{pr2}$请注意,您不能简单地写下:
Python永远不会将一个简单的名称解析为一个方法/staticmethod;对于Python来说,
a()
必须是一个本地或全局的函数调用。必须使用self.a
引用实例,或者使用B.a
引用类。在在python中,
self
与当前的类引用一样是显式的。不要与Java的隐式this
混淆。在相关问题 更多 >
编程相关推荐