【问题标题】:Why do I need to repeat method definition while using django.utils.decorators method_decorator in inherited class为什么在继承类中使用 django.utils.decorators method_decorator 时需要重复方法定义
【发布时间】:2012-03-22 09:19:24
【问题描述】:

您好,我正在尝试了解 django.utils.decorators method_decorator 装饰器。 method_decorator 将函数装饰器转换为类方法装饰器。

此装饰器的来源位于 (https://github.com/django/django/blob/master/django/utils/decorators.py)

我的示例函数装饰器:

def run_eight_times(myfunc):
    def inner_func(*args, **kwargs):
        for i in range(8):
            myfunc(*args, **kwargs)
    return inner_func

我的示例基类:

class Myclass(object):

    def __init__(self,name,favorite_dish):
        self.name = name
        self.favorite_dish = favorite_dish

    def undecorated_function(self):
        print "%s likes spam in his favorite dish %s" % (self.name,self.favorite_dish)

现在我想创建一个继承类,它使用 django.utils.decorators 方法_decorator 来装饰 Myclass 方法 undecorated_function。 为了让 method_decorator 工作,我需要在继承的类中重新定义函数。

所以这行得通:

class Myrepetitiveclass(Myclass):

    def __init__(self,*args, **kwds):
        Myclass.__init__(self,*args,**kwds)

    @method_decorator(run_eight_times)
    def undecorated_function(self):
        print "%s likes spam in his favorite dish %s" % (self.name,self.favorite_dish) 

noisier_me = Myrepetitiveclass("harijaynoisyclass","moreeggs")
noisier_me.undecorated_function()

我有点困惑,不知道为什么下面的代码不起作用并给出语法错误。

这不会被正确解释并给出语法错误。

class Myrepetitiveclass(Myclass):

    def __init__(self,*args, **kwds):
        Myclass.__init__(self,*args,**kwds)

    # Why does this not work? and gives a syntax error?

    @method_decorator(run_eight_times)
    self.undecorated_function

如何在不重新定义子类的情况下装饰函数?

【问题讨论】:

    标签: python inheritance decorator django-class-based-views


    【解决方案1】:

    self 不存在于该范围内 - 它仅存在于方法中,并且仅存在于方法中,因为它是作为第一个参数传递的。

    这样做的方法是重写方法,简单地调用超类方法:

    @method_decorator(run_eight_times)
    def undecorated_function(self):
        super(Myrepetitiveclass, self).undecorated_function() 
    

    另外,您的其他代码上有两个 cmets:如果您只是调用父方法,则没有必要覆盖 __init__ 方法,但如果您确实需要,您应该使用 super,就像我在这里所做的那样,而不是使用超类本身的名称。

    【讨论】:

    • 感谢您的帮助。我有另一个问题,它是相关的,我不想开始一个新线程。为什么我需要上面代码中的 django.utils.decorators @method_decorator。即使有 \@run_eight_times 仍然用相同的结果装饰 undecorated_function
    猜你喜欢
    • 2015-01-29
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 2021-01-01
    • 1970-01-01
    • 2015-04-28
    • 2019-11-12
    相关资源
    最近更新 更多