多个python装饰器
我有一个Django模型MyModel和一个修饰方法my_方法。 我希望装饰师对我的方法执行一些检查: 如果检查成功,my_方法应该返回一个字符串 如果检查没有成功,my_方法应该返回装饰程序返回的失败消息 逻辑如下:多个python装饰器,python,decorator,python-decorators,Python,Decorator,Python Decorators,我有一个Django模型MyModel和一个修饰方法my_方法。 我希望装饰师对我的方法执行一些检查: 如果检查成功,my_方法应该返回一个字符串 如果检查没有成功,my_方法应该返回装饰程序返回的失败消息 逻辑如下: # models.py class MyModel(models.Model): @decorator1 @decorator2 def my_method(self, request, *args, **kwargs): return u
# models.py
class MyModel(models.Model):
@decorator1
@decorator2
def my_method(self, request, *args, **kwargs):
return u'The result that must be returned if all the checks performed by the decorator succeed'
# decorators.py
from functools import wraps
# decorator1 checks if certain conditions are met. If yes, it returns the decorated method (method_to_decorate); if not, it returns a tuple
def decorator1(method_to_decorate):
@wraps(method_to_decorate)
def wrapper1(self, request, *args, **kwargs):
if a_condition :
return method_to_decorate(self, request, *args, **kwargs)
else:
# we return a failure message
return ('failure', 'message')
return wrapper1
# in decorator2, we want to know if the check performed by decorator1 was successful
# in case of success, we perform decorator2's check
# in case of failure, decorator2 should simply pass the failure message returned by decorator1
def decorator2(method_to_decorate):
@wraps(method_to_decorate)
def wrapper2(self, request, *args, **kwargs):
# if the first decorator succeeded
if decorator1_s_test_was_successful:
# we check if the conditions of the second decorator are met
if decorator2_s_test_was_successful:
# we return the method
return method_to_decorate(self, request, *args, **kwargs)
else:
# we return a failure message
return ('another failure', 'message')
# if the first decorator did not succeed
else: # decorator1 returned a tuple : ('failure', 'message')
return the_failure_that_decorator1_returned
return wrapper2
因此,如果decorator1返回一个失败,我希望我的模型实例的实例返回“failure”,“message”。如果decorator1成功了,但decorator2没有成功,那么我将看到“另一个失败”,“消息”。如果所有的测试都通过了,那么u'如果装饰程序执行的所有检查都成功,那么必须返回的结果'
如果decorator1的检查成功通过,我不知道如何签入decorator2。我试图通过在decorator2中检查方法的类型来实现这一点,但是类型似乎使用了原始方法本身,而不是decorator1返回的结果,就好像decorators不知道以前的decorator执行的操作一样
提前谢谢你 如果希望decorator2检查decorator1返回的任何内容,则需要交换@decorator1和@decorator2行:
@decorator2
@decorator1
def my_method(self, request, *args, **kwargs):
return u'The result that must be returned if all the checks performed by the decorator succeed'
现在decorator2将封装decorator1返回的任何方法,因此您可以检查该方法返回的内容
def decorator2(method_to_decorate):
@wraps(method_to_decorate)
def wrapper2(self, request, *args, **kwargs):
result = method_to_decorate(self, request, *args, **kwargs)
if isinstance(result, tuple) and result and result[0] == 'failure':
# decorator1 returned a failure
return result
else:
# decorator1 passed through the wrapped method call
if decorator2_s_test_was_successful:
return result
else:
return ('another failure', 'message')
return wrapper2
如果希望decorator2检查decorator1返回的任何内容,则需要交换@decorator1和@decorator2行:
@decorator2
@decorator1
def my_method(self, request, *args, **kwargs):
return u'The result that must be returned if all the checks performed by the decorator succeed'
现在decorator2将封装decorator1返回的任何方法,因此您可以检查该方法返回的内容
def decorator2(method_to_decorate):
@wraps(method_to_decorate)
def wrapper2(self, request, *args, **kwargs):
result = method_to_decorate(self, request, *args, **kwargs)
if isinstance(result, tuple) and result and result[0] == 'failure':
# decorator1 returned a failure
return result
else:
# decorator1 passed through the wrapped method call
if decorator2_s_test_was_successful:
return result
else:
return ('another failure', 'message')
return wrapper2
decorator将按照您将它们放在decorator方法之上的顺序被调用,并且给定您的程序结构,如果decorator1失败,则不会调用decorator2,因此无需检查decorator1在decorator2中是否成功 一个稍微简单的例子
from functools import wraps
def decorator1(f):
@wraps(f)
def wrapper(a):
if a >= 1:
return f(a)
return 'failed in decorator 1'
return wrapper
def decorator2(f):
@wraps(f)
def wrapper(a):
if a >= 2:
return f(a)
return 'failed in decorator 2'
return wrapper
@decorator1
@decorator2
def my_func(a):
return 'success'
print my_func(0)
print my_func(1)
print my_func(2)
…它打印
failed in decorator 1
failed in decorator 2
success
decorator将按照您将它们放在decorator方法之上的顺序被调用,并且给定您的程序结构,如果decorator1失败,则不会调用decorator2,因此无需检查decorator1在decorator2中是否成功 一个稍微简单的例子
from functools import wraps
def decorator1(f):
@wraps(f)
def wrapper(a):
if a >= 1:
return f(a)
return 'failed in decorator 1'
return wrapper
def decorator2(f):
@wraps(f)
def wrapper(a):
if a >= 2:
return f(a)
return 'failed in decorator 2'
return wrapper
@decorator1
@decorator2
def my_func(a):
return 'success'
print my_func(0)
print my_func(1)
print my_func(2)
…它打印
failed in decorator 1
failed in decorator 2
success
好的,谢谢你,Martijn,这很有效。我害怕颠倒装饰师的顺序,但这确实奏效了。好的,谢谢你,Martijn,这很有效。我害怕改变装潢师的顺序,但这确实奏效了。