【问题标题】:How to use Python super() when returning values and keeping track of internal state?返回值和跟踪内部状态时如何使用 Python super()?
【发布时间】:2021-12-13 03:59:22
【问题描述】:

我正在尝试在 Python (3.7.6) 中构造一个调用 super() 的类继承的玩具示例。我想跟踪链中中间类的状态,并且我想让委托的类方法返回一个值。我认为这应该很简单,但我得到了一个奇怪的结果。

(我的最小示例基于this tutorial。)

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

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() 功能的一些基本知识,如果有人可以提供任何帮助,我将不胜感激!

【问题讨论】:

    标签: python python-3.x oop super


    【解决方案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)
                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)
    

    【讨论】:

    • 解释错误以及您如何修复它。
    • 谢谢,刚刚编辑
    猜你喜欢
    • 2010-11-27
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    相关资源
    最近更新 更多