如何判断某个函数是否由指定的wrap函数包装?
如何判断函数是否由指定包装函数生成?
先看示例代码:
def wrap( x ): def wrapped( y ): return x + y return wrapped f = wrap( 1 )
打印f时会输出:
>>> f <function wrap.<locals>.wrapped at 0x10067cf40>
虽然输出里能看到wrap的字样,但有没有可靠的方法确认f确实是由wrap函数包装生成的?
几种可行的方法:
手动添加自定义标记(最可靠)
直接在内部函数里加个专属属性,指向外层的wrap函数,后续检查这个属性就能准确判断:def wrap(x): def wrapped(y): return x + y # 给内部函数加标识属性 wrapped.__generated_by__ = wrap return wrapped f = wrap(1) # 验证 print(getattr(f, '__generated_by__', None) is wrap) # 输出 True这种方法完全可控,不会出现误判,只要代码没被恶意修改,就能100%确认关联关系。
利用
__qualname__属性(简便但有局限)
函数的__qualname__会保留嵌套函数的层级名称,比如这里f.__qualname__的值是'wrap.<locals>.wrapped',可以通过判断名称前缀来间接验证:print(f.__qualname__.startswith('wrap.')) # 输出 True但这个方法有漏洞:如果有其他同名的
wrap函数,或者代码被修改了函数名称,就会失效,只能作为辅助判断。查看闭包信息(辅助验证)
内部函数wrapped引用了外层的x,属于闭包函数,可以通过__closure__属性查看闭包变量,但这只能证明它是闭包,没法直接关联到wrap,配合__qualname__能提升判断的准确性:# 检查是否存在闭包 print(f.__closure__ is not None) # 输出 True # 查看闭包中保存的x值 print(f.__closure__[0].cell_contents) # 输出 1
总结
最稳妥的方式是手动添加自定义标识属性,其他依赖函数名称或结构的方法都存在被篡改或误判的风险。
内容的提问来源于stack exchange,提问作者greg
相关产品推荐
相关产品推荐

