Skip to main content
 首页 » 编程设计

python之多个 python 装饰器

2025年05月04日16duanxz

我有一个带有修饰方法 (my_method) 的 Django 模型 (MyModel)。 我希望装饰器对 my_method 执行一些检查:

  • 如果检查成功,my_method 应该返回一个字符串;

  • 如果检查不成功,my_method 应该返回装饰器返回的失败消息。

逻辑如下:

# 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 返回失败,我希望 an_instance_of_my_model_instance.my_method(request) 返回 ('failure', 'message')。如果 decorator1 成功但 decorator2 不成功,我会期望('另一个失败','消息')。而如果所有的测试都通过了,u'如果装饰器执行的所有检查都成功必须返回的结果'

如果 decorator1 的检查成功通过,我不知道如何检查 decorator2。我试图通过检查 decorator2 中 method_to_decorate 的 type() 来做到这一点,但似乎类型使用原始方法本身,而不是 decorator1 返回的结果(好像装饰器不知道以前的装饰器执行的操作) .

提前致谢!

请您参考如下方法:

装饰器将按照您将它们放在装饰方法之上的顺序调用,并且给定您的程序结构,如果 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