如何创建新的闭包单元对象?


问题内容

我需要猴子补丁库来替换符号的实例,并且它被某些函数闭包引用。我需要复制这些函数(因为我也需要访问该函数的原始未打补丁版本),但是它__closure__是不可变的,而且我做不到copy.copy,因此如何在Python
2.7中创建新的闭包单元对象?

我例如给出这个功能

def f():
    def incorrectfunction():
        return 0
    def g():
        return incorrectfunction()
    return g

def correctfunction():
    return 42

func = f()
patched_func = patchit(f)   # replace "incorrectfunction"
print func(), patched_func()

我想看看

0, 42

问题答案:

制作封闭单元格的简单方法是进行封闭:

def make_cell(val=None):
    x = val
    def closure():
        return x
    return closure.__closure__[0]

如果要重新分配现有单元格的内容,则需要进行C API调用:

import ctypes
PyCell_Set = ctypes.pythonapi.PyCell_Set

# ctypes.pythonapi functions need to have argtypes and restype set manually
PyCell_Set.argtypes = (ctypes.py_object, ctypes.py_object)

# restype actually defaults to c_int here, but we might as well be explicit
PyCell_Set.restype = ctypes.c_int

PyCell_Set(cell, new_value)

当然,仅CPython。