<p>说真的:你真的不想这么做。在</p>
<p>但是,对于Python的高级用户来说理解这一点是很有用的,所以我将对此进行解释。在</p>
<p>Cells和freevar是在创建闭包时指定的值。例如</p>
<pre><code>def f():
a = 1
def func():
print(a)
return func
</code></pre>
<p><code>f</code>返回基于<code>func</code>的闭包,存储对<code>a</code>的引用。该引用存储在一个单元中(实际上是在一个freevar中,但是哪个单元取决于实现)。您可以检查:</p>
^{pr2}$
<p>(“细胞”和“自由变量”非常相似。freevar有名称,其中单元格有索引。它们都储存在<code>func.__closure__</code>中,细胞是第一位的。这里我们只关心<code>freevars</code>,因为这就是<code>__class__</code>是什么。)</p>
<p>一旦理解了这一点,就可以看到super()实际上是如何工作的。任何包含对<code>super</code>的调用的函数实际上都是一个闭包,其中有一个名为<code>__class__</code>的freevar(如果您自己引用<code>__class__</code>也会添加该值):</p>
<pre><code>class foo:
def bar(self):
print(__class__)
</code></pre>
<p>(警告:这是事情变得邪恶的地方。)</p>
<p>这些细胞在<code>func.__closure__</code>中可见,但它是只读的;您无法更改它。更改它的唯一方法是创建一个新函数,这是用<code>types.FunctionType</code>构造函数完成的。但是,您的<code>__init__</code>函数根本没有<code>__class__</code>自由变量,因此我们需要添加一个。这意味着我们还必须创建一个新的代码对象。在</p>
<p>下面的代码就是这样做的。我添加了一个基类<code>B</code>,以便于说明。这段代码做了一些假设,例如<code>__init__</code>还没有一个名为<code>__class__</code>的自由变量。在</p>
<p>这里还有另一个问题:似乎没有单元类型的构造函数。为了解决这个问题,我们创建了一个伪函数<code>C.dummy</code>,它有我们需要的cell变量。在</p>
<pre><code>import types
class B(object):
def __init__(self):
print("base")
class C(B):
def dummy(self): __class__
def __init__(self):
print('calling __init__')
super().__init__()
def MakeCodeObjectWithClass(c):
"""
Return a copy of the code object c, with __class__ added to the end
of co_freevars.
"""
return types.CodeType(c.co_argcount, c.co_kwonlyargcount, c.co_nlocals,
c.co_stacksize, c.co_flags, c.co_code, c.co_consts, c.co_names,
c.co_varnames, c.co_filename, c.co_name, c.co_firstlineno,
c.co_lnotab, c.co_freevars + ('__class__',), c.co_cellvars)
new_code = MakeCodeObjectWithClass(__init__.__code__)
old_closure = __init__.__closure__ or ()
C.__init__ = types.FunctionType(new_code, globals(), __init__.__name__,
__init__.__defaults__, old_closure + (C.dummy.__closure__[0],))
if __name__ == '__main__':
c = C()
</code></pre>