<p>好的,经过一些实验后,我设法提供了一个“修复”来允许类初始化,允许使用<code>super()</code>。在</p>
<p>首先,模块要“修复”初始化方法:</p>
<pre class="lang-py prettyprint-override"><code># ./PythonFix.py
import inspect
import types
def IsCellEmpty(cell):
"""Lets keep going, deeper !"""
try:
cell.cell_contents
return False
except ValueError:
return True
def ClosureFix(cls, functionContainer):
"""This is where madness happens.
I didn't want to come here. But hey, lets get mad.
Had to do this to correct a closure problem occuring in
Python < 3.6, joy.
Huge thanks: https://stackoverflow.com/a/4885951/7983255
"""
# Is the class decorated with @classmethod somehow
isclassmethod = inspect.ismethod(functionContainer) and functionContainer.__self__ is cls
if isclassmethod:
function = functionContainer.__func__
else:
function = functionContainer
# Get cells and prepare a cell holding ref to __class__
ClosureCells = function.__closure__ or ()
ClassCell_Fix = (lambda: cls).__closure__[0]
# Shortcut
c = function.__code__
HasClassFreevar = '__class__' in c.co_freevars
HasEmptyCells = any(IsCellEmpty(cell) for cell in ClosureCells)
if HasClassFreevar and not HasEmptyCells: # No fix required.
return classmethod(function)
Freevars_Fixed = c.co_freevars
Closure_Fixed = ClosureCells
if not HasClassFreevar:
Freevars_Fixed += ('__class__',)
Closure_Fixed += (ClassCell_Fix,)
elif HasEmptyCells: # This is silly, but for what I'm doing its ok.
Closure_Fixed = tuple(ClassCell_Fix if IsCellEmpty(cell) else cell for cell in ClosureCells)
# Now the real fun begins
PyCode_fixedFreevars = 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, Freevars_Fixed, c.co_cellvars
)
# Lets fetch the last closure to add our __class__ fix
FixedFunction = types.FunctionType(
PyCode_fixedFreevars, function.__globals__, function.__name__,
function.__defaults__, Closure_Fixed
)
# Lets rewrap it so it is an actual classmethod (which it should be):
return classmethod(FixedFunction)
</code></pre>
<p>现在,组件代码:</p>
^{pr2}$
<p>说句公道话,我很高兴能完成。希望这能帮助那些想要初始化类的人(至少在Python3.6之前的环境中……)。在</p>