防止装饰器在python中的同一函数上使用两次 [英] Prevent decorator from being used twice on the same function in python
问题描述
我有一个装饰器:
from functools import wraps
def d(f):
@wraps(f)
def wrapper(*args,**kwargs):
print 'Calling func'
return f(*args,**kwargs)
return wrapper
我想防止它两次修饰相同的函数,例如防止诸如此类的事情:
And I want to prevent it from decorating the same function twice, e.g prevent things such as:
@d
@d
def f():
print 2
我能想到的唯一可能的解决方案是使用字典存储装饰器已经装饰的功能,并在请求时引发异常装饰字典中存在的功能。
请告诉您是否有更好的主意...
Only possible solution I could think of is using a dict to store the functions the decorator has already decorated and raising an exception if asked to decorate a function that exists in the dict. Do tell if you have a better idea...
推荐答案
我会将信息存储在函数本身中。如果多个装饰器决定使用同一变量,则有发生冲突的风险,但是如果它只是您自己的代码,则应该可以避免使用该变量。
I'd store the information in the function itself. There is a risk of a conflict if multiple decorators decide to use the same variable, but if it's only your own code, you should be able to avoid it.
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
属性,则您将不知道装饰了什么。
This assumes that you control all the decorators used. If there is a decorator that doesn't copy the _decorated_with
attribute, you will not know what is it decorated with.
这篇关于防止装饰器在python中的同一函数上使用两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!