代码之家  ›  专栏  ›  技术社区  ›  Aran-Fey Swapnil

为什么分配给类单元格会打断super?

  •  1
  • Aran-Fey Swapnil  · 技术社区  · 6 年前

    Why is Python 3.x's super() magic? 并理解使用 super __class__ 在方法中,将自动创建 __班级__

    class Demo:
        def meth(self):
            super().meth()
    
    >>> Demo.meth.__closure__
    (<cell at 0x7f4572056138: type object at 0x564bda0e5dd8>,)
    >>> Demo.meth.__closure__[0].cell_contents
    <class '__main__.Demo'>
    

    def outer():
        x = 3
        def inner():
            print(x)
    
        x = 5
        return inner
    
    inner = outer()
    inner()  # output: 5
    
    >>> inner.__closure__
    (<cell at 0x7f2183a5e138: int object at 0x7f2184600460>,)
    

    但是试图重新分配 __班级__ 电池制造 超级的

    class Demo:
        def meth(self):
            __class__ = Demo
            super().meth()
    
    Demo().meth()
    
    Traceback (most recent call last):
      File "untitled.py", line 8, in <module>
        Demo().meth()
      File "untitled.py", line 6, in meth
        super().meth()
    RuntimeError: super(): __class__ cell not found
    

    为什么会这样?为什么不能 __班级__

    1 回复  |  直到 6 年前
        1
  •  2
  •   user2357112    6 年前

    nonlocal 语句分配给闭包变量,包括magic __class__ 闭包变量。分配给 __班级__ 没有一个 非局部的 语句创建一个局部变量来隐藏magic闭包变量。

    __班级__ 表现得像是当地人 meth ,但实际上它的行为就好像它是一个不可见的伪作用域的局部,在这个伪作用域中 Demo 是嵌套的。如果它被视为当地的 ,你不需要 非局部的 .

    如果你加了一个 非局部的 声明、实施 actually will allow you 要重新指定magic闭包变量,请执行以下操作:

    class Foo:
        def meth(self):
            nonlocal __class__
            __class__ = 3
            super()
    
    Foo().meth()
    

    结果:

    Traceback (most recent call last):
      File "./prog.py", line 7, in <module>
      File "./prog.py", line 5, in meth
    RuntimeError: super(): __class__ is not a type (int)