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

2024-10-01 11:34:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要monkey-patch我的库来替换一个符号的实例,它被一些函数闭包引用。我需要复制这些函数(因为我还需要访问该函数的原始未修补版本),但是__closure__是不可变的,我不能{}它,那么如何在Python2.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()

我想看看

^{pr2}$

Tags: 对象实例函数版本returndef符号monkey
3条回答

lambda中:

def make_cell(value):
    fn = (lambda x: lambda: x)(value)
    return fn.__closure__[0]

https://github.com/nedbat/byterun/blob/master/byterun/pyobj.py#L12得到答案

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

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

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

^{pr2}$

当然,只有CPython。在

如果你想要一个空单元格(这就是我发现这个问题的原因)(一个引用它会引发NameError: free variable '...' referenced before assignment in enclosing scope并访问它的cell.cell_contents引发一个ValueError: Cell is empty),你可以使一个值成为一个局部变量,但永远不要让它被赋值:

def make_empty_cell():
    if False:
        # Any action that makes `value` local to `make_empty_cell`
        del value
    return (lambda: value).__closure__[0]

你可以这样组合它们:

^{pr2}$

因此,不带参数的调用将返回一个空单元格,而对于任何值,则返回具有该值的单元格。在

如果不关心空单元格,可以执行以下操作:

def make_cell(value):
    return (lambda: value).__closure__[0]

注意,在旧的python2中它是func_closure,而不是{}。在

相关问题 更多 >