首页 > 解决方案 > Python:如何断言闭包的起源?

问题描述

如何断言返回的函数源自外部函数?

def wraps(val):
    def func():
        return val
    return func

a = wraps(5)
# assert that a comes from wraps()

我可以看到它a.__qualname__包含全局 func: 的名称wraps.<locals>.func,所以我可以基于它进行测试,但那是 The Right Way™️ 吗?

作为上述观点的扩展,鉴于__qualname__属性包含封闭函数的名称,这是否意味着它的 ref 被埋在某处,或者该字符串是否会在创建函数时生成并针对它存储当时丢弃的外部函数的引用?

标签: python

解决方案


你不能这样做,因为函数是在每次wraps调用中构建的:

>>> a = wraps(1)
>>> b = wraps(1)
>>> a is b
False
>>> id(a)
139880648604800
>>> id(b)
139880648604936

解决方案是返回实际的基本情况并将其放在外面并返回其中的一个partial

def func(val):
    return val

from functools import partial
def wraps(val):
    return partial(func, val)

这样它就可以在您需要的任何地方进行断言。

>>> f = wraps(10)
>>> f.func
<function func at 0x7f38805efd90>
>>> assert f.func is func
>>> assert f.func is not func
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

推荐阅读