我试图在一个类方法中构建一个控制结构,它接受一个函数作为输入,并且如果一个函数被装饰或没有装饰,它就有不同的行为。关于如何构建一个行为如下的函数is_decorated
,有什么想法吗?
def dec(fun):
# do decoration
def func(data):
# do stuff
@dec
def func2(data):
# do other stuff
def is_decorated(func):
# return True if func has decorator, otherwise False
is_decorated(func) # False
is_decorated(func2) # True
4条答案
按热度按时间eqqqjvef1#
是的,这相对容易,因为函数可以添加任意的属性,所以装饰器函数可以在它做它的事情时添加一个:
ymzxtsji2#
有几种方法可以识别 * 函数**是否被 Package /修饰。
TLDR解决方案
情景A
如果我们假设装饰器使用辅助装饰器
functools.wraps
,那么它非常简单,因为我们的装饰函数将在后面具有属性__wrapped__
。情景B
如果我们在decorator的定义中没有使用
wraps
,那么它就有点不同了。结论
还有其他更复杂的方法来检查这一点,然而可读性和完整性一样重要,这个解决方案尽可能简单。正如前面的代码块中所提到的,这个解决方案的唯一“漏洞”是以下情况:
q9rjltbz3#
如果利用基于类的装饰器呢?使用
__call__
方法使类成为可调用类,就像它是一个函数一样。ddhy6vgd4#
一般来说,你不能。会留下痕迹的装修师没什么特别的。根据优秀的Primer on Python Decorators教程,“装饰器为调用higher-order functions提供了一个简单的语法”。
本教程中的一个快速说明性示例:
你看到
do_twice
内部的wrapper_do_twice
实际上只是调用了传递的函数两次了吗?它绝不会修改函数,所以不可能告诉(没有inspection,它不会这样做)函数被修饰了。然而,如果你正在编写自己的装饰器,或者你知道你可以利用你正在使用的装饰器修改装饰函数(与上面的例子相反,它不修改函数),那么你可以直接检查剩下的任何标记。请参阅this问题的示例。