首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个python装饰器

多个python装饰器
EN

Stack Overflow用户
提问于 2013-06-19 12:33:24
回答 2查看 4.6K关注 0票数 1

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

  • 如果检查成功,my_method应该返回一个字符串;
  • 如果检查没有成功,my_method应该返回装饰器返回的失败消息。

逻辑如下:

代码语言:javascript
复制
# 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

因此,如果an_instance_of_my_model_instance.my_method(request)返回一个失败,我希望decorator1返回(' failure ','message')。如果decorator1成功了,但decorator2没有成功,我会期待(‘另一个失败’,'message')。如果所有的测试都通过了,那么如果装潢工执行的所有检查都成功的话,必须返回的结果。

如果装饰1的检查成功通过,我不知道如何签入decorator2。我试图通过检查method_to_decorate在decorator2中的类型()来完成它,但似乎类型使用的是原始方法本身,而不是decorator1返回的结果(好像装饰器不知道以前的装饰器所执行的操作)。

提前谢谢你!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-19 12:47:34

如果要让@decorator1@decorator2检查返回的任何decorator1,则需要交换decorator2行:

代码语言:javascript
复制
@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返回的任何方法,因此您可以检查该方法返回的内容。

代码语言:javascript
复制
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
票数 5
EN

Stack Overflow用户

发布于 2013-06-19 12:55:22

将按照您将它们置于修饰方法之上的顺序调用装饰器,并且根据您的程序结构,如果decorator2失败,则不会调用decorator1,因此不需要检查decorator1decorator2中是否成功。

一个稍微简单的例子..。

代码语言:javascript
复制
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)

...which指纹..。

代码语言:javascript
复制
failed in decorator 1
failed in decorator 2
success
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17191316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档