我可以获得应用于函数的装饰器列表吗?

时间:2012-02-29 04:15:58

标签: python decorator

有没有什么方法可以获得应用于函数的装饰器列表,而不需要像装饰装饰器那样使用hackish?

4 个答案:

答案 0 :(得分:3)

我很难发布这样的答案,因为有些东西似乎总是在python标准库的深处冒出来证明我错了。但我很确定答案是肯定的。

问题在于装饰器本身就是函数 - 整个@foo只是func = foo(func)的语法糖 - 所以它们不会给你任何额外的功能您。这不是很多。

您可能可以在func_dictfunc_globalsfunc_defaultsfunc_closure等方面进行搜索,并做出一些猜测,但不太可能一个很好的通用解决方案,不涉及将行为手动编码到装饰器中。或者,正如您所说,通过装饰装饰器。

答案 1 :(得分:3)

不是真的。首先,因为并非所有装饰器都返回包装函数;装饰器可以简单地修改现有的函数(也许在它上面设置一个属性) - 很明显,Python没有记录触及每个属性的函数。其次,虽然您可以向垃圾收集器询问包含对装饰函数的引用的闭包,以及具有该闭包的函数,但并非每个在闭包中保存对另一个函数的引用的函数都是由装饰器应用的包装器。然后是带有参数的装饰器的问题;在进入实际的装饰功能之前,还有一层额外的内部函数。最后,并非所有装饰器都是函数,并非所有装饰对象都是函数。

简而言之,你可能会在某些时候对它进行近似,但即使它有效,它也将是一个只适用于CPython的巨大黑客攻击。没有任何简单的,有记录的方法可以做到这一点。

答案 2 :(得分:1)

我相信这是不可能的,因为装饰者可以选择替换函数,包装函数,返回他们想要的任何东西。它并没有被“应用”到这个功能上。

答案 3 :(得分:0)

正如其他答案所说,装饰者无法包装该函数,只是修改它 - 在这种情况下,你将无法找到它们。

对于包装器装饰器,你可以使用Python的调试钩子 - 它不会轻松,并且不会成为" clean" - 但是可以这样做:每次进入函数时都会调用一个调试钩子,然后调用你的装饰函数 - 每次调用你的钩子时你都进入了一个新的功能 - 使用内省来看看这是否是你的" final"功能(如果你的装饰者不自己使用functools.wrap很容易,你所需的功能是唯一一个保留原始__name__属性的功能,否则比较棘手) - 参见文档 sys.settrace以及bdb模块,检查您是否想出了什么。

但是当你想到这一点时,装饰装饰师再也不会看起来那么黑了,是吗?

相关问题