python - 防止装饰器在Python中的同一个函数上使用两次

标签 python decorator

我有一个装饰器:

from functools import wraps
def d(f):
    @wraps(f)
    def wrapper(*args,**kwargs):
        print 'Calling func'
        return f(*args,**kwargs)
    return wrapper

我想防止它两次装饰同一个函数,例如防止以下情况:

@d
@d
def f():
   print 2

我能想到的唯一可能的解决方案是使用字典来存储装饰器已经装饰的函数,并在要求装饰字典中存在的函数时引发异常。 如果您有更好的想法,请告诉我们...

最佳答案

我会将信息存储在函数本身中。如果多个装饰器决定使用同一个变量,则存在冲突的风险,但如果这只是您自己的代码,您应该能够避免它。

def d(f):
    if getattr(f, '_decorated_with_d', False):
        raise SomeException('Already decorated')
    @wraps(f)
    def wrapper(*args,**kwargs):
        print 'Calling func'
        return f(*args,**kwargs)
    wrapper._decorated_with_d = True
    return wrapper

另一个选项可以是这样的:

def d(f):
    decorated_with = getattr(f, '_decorated_with', set())
    if d in decorated_with:
        raise SomeException('Already decorated')
    @wraps(f)
    def wrapper(*args,**kwargs):
        print 'Calling func'
        return f(*args,**kwargs)
    decorated_with.add(d)
    wrapper._decorated_with = decorated_with
    return wrapper

这假设您控制所有使用的装饰器。如果有一个装饰器不复制_decorated_with属性,你将不知道它装饰的是什么。

关于python - 防止装饰器在Python中的同一个函数上使用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1547222/

相关文章:

python - 我的问答游戏中的draw()函数无法正常工作

Python 列表切片效率

python - BeautifulSoup 文本挖掘 - 变量字符串

python - 文件未找到错误: [Errno 2] No such file or directory: 'test_user1_user_id'

python - 出于测试目的访问原始装饰函数

python - 在python中装饰递归函数

类中的 Python 装饰器

python - python unittest subTest 和skipTest 之间的交互是否定义了?

python - 陷阱异常,再试一次Python中的装饰器

c# - 如何在责任链中注入(inject)下一个处理程序的依赖?