在返回值和跟踪内部状态时如何使用Python super() ?



我试图构建一个在Python(3.7.6)中调用super()的类继承的玩具示例。我希望跟踪链中中产阶级的状态,并且希望委托的类方法返回一个值。我认为这应该是直截了当的,但我得到了一个奇怪的结果。

(我基于本教程的最小示例)

我可以设置一个中产阶级跟踪状态的例子,没有问题:

In [1]: class Root:
...:     def draw(self):
...:         # the delegation chain stops here
...:         assert not hasattr(super(), 'draw')
...: 
...: class Shape(Root):
...:     def __init__(self, shapename, **kwds):
...:         self.shapename = shapename
...:         self.has_run = False
...:         super().__init__(**kwds)
...:     def draw(self):
...:         if not self.has_run:
...:             print('Drawing for the first time.  Setting shape to:', self.shapename)
...:             self.has_run = True
...:         else:
...:             print('Drawing again.  Setting shape to:', self.shapename)
...: 
...:         super().draw()
...: 
...: class ColoredShape(Shape):
...:     def __init__(self, color, **kwds):
...:         self.color = color
...:         super().__init__(**kwds)
...:     def draw(self):
...:         print('Drawing.  Setting color to:', self.color)
...:         super().draw()
...: 
...: cs = ColoredShape(color='blue', shapename='square')
...: print('*** first pass')
...: cs.draw()
...: print('*** second pass')
...: cs.draw()
*** first pass
Drawing.  Setting color to: blue
Drawing for the first time.  Setting shape to: square
*** second pass
Drawing.  Setting color to: blue
Drawing again.  Setting shape to: square

然而,一旦我修改方法返回一个值,我就失去了跟踪状态的能力:

In [2]: class Root:
...:     def draw(self):
...:         # the delegation chain stops here
...:         assert not hasattr(super(), 'draw')
...: 
...: class Shape(Root):
...:     def __init__(self, shapename, **kwds):
...:         self.shapename = shapename
...:         self.has_run = False
...:         super().__init__(**kwds)
...:     def draw(self):
...:         if not self.has_run:
...:             print('Drawing for the first time.  Setting shape to:', self.shapename)
...:             return 'a'
...:             self.has_run = True
...:         else:
...:             print('Drawing again.  Setting shape to:', self.shapename)
...:             return 'b'
...:         super().draw()
...: 
...: class ColoredShape(Shape):
...:     def __init__(self, color, **kwds):
...:         self.color = color
...:         super().__init__(**kwds)
...:     def draw(self):
...:         print('Drawing.  Setting color to:', self.color)
...:         foo = super().draw()
...:         return [foo] * 3
...: 
...: cs = ColoredShape(color='blue', shapename='square')
...: print('*** first pass')
...: out = cs.draw()
...: print(out)
...: print('*** second pass')
...: out = cs.draw()
...: print(out)
*** first pass
Drawing.  Setting color to: blue
Drawing for the first time.  Setting shape to: square
['a', 'a', 'a']
*** second pass
Drawing.  Setting color to: blue
Drawing for the first time.  Setting shape to: square
['a', 'a', 'a']

我觉得我错过了一些关于super()功能的基本内容,我将感谢人们可以给予的任何帮助!

这是个非常愚蠢的错误。在链中的中产阶级中,我在设置内部状态变量之前返回。这可以通过在任何return语句之前更新状态变量来纠正。

更正以下代码:

class Root:
def draw(self):
# the delegation chain stops here
assert not hasattr(super(), 'draw')
class Shape(Root):
def __init__(self, shapename, **kwds):
self.shapename = shapename
self.has_run = False
super().__init__(**kwds)
def draw(self):
if not self.has_run:
print('Drawing for the first time.  Setting shape to:', self.shapename)
out = 'a'
self.has_run = True
else:
print('Drawing again.  Setting shape to:', self.shapename)
out = 'b'
super().draw()
return out
class ColoredShape(Shape):
def __init__(self, color, **kwds):
self.color = color
super().__init__(**kwds)
def draw(self):
print('Drawing.  Setting color to:', self.color)
foo = super().draw()
return [foo] * 3
cs = ColoredShape(color='blue', shapename='square')
print('*** first pass')
out = cs.draw()
print(out)
print('*** second pass')
out = cs.draw()
print(out)

最新更新