在子类中如何装饰继承的方法? [英] How would one decorate an inherited method in the child class?

查看:85
本文介绍了在子类中如何装饰继承的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不太确定如何在继承的方法上使用装饰器。装饰器通常放在定义之前,但对于继承的函数,定义是在父类而不是子类中给出的。我想避免在子类中重写方法的定义,而只需指定将装饰器放在继承的方法周围。

I'm not quite sure how to use a decorator on an inherited method. Normally decorators are put before the definition but for an inherited function the definition is given in the parent and not the child class. I would like to avoid rewriting the definition of the method in the child class and simply specify to put the decorator around the inherited method.

为了使自己更清楚,这是一个我的意思的工作示例:

To make myself clearer, here is a working example of what I mean:

class Person():
    def __init__(self, age):
        self.age = age

    @classmethod
    def gets_drink(cls, ):
        print "it's time to get a drink!"
        return "A beer"

def dec(some_f):
    def legal_issue(obj,):
        some_f(obj)
        return 'A Coke'
    return legal_issue

class Child(Person):
    def __init__(self, age):
        Person.__init__(self, age=age)

    #in principle i'd like to write
    #@dec
    #self.gets_drink
    #which does not work
    #the only working way I found is by defining the method as a classmethod
    #and write this:

    @dec
    def gets_drink(self, ):
        return Person.gets_drink()

dad = Person(42)
son = Child(12)

print dad.gets_drink()
print son.gets_drink()

此示例中的工作方式有效,但对我来说看起来有点怪异,用调用方法代替了原始方法只能将装饰器放进去。同样,要使此方法起作用,需要将该方法定义为父类中的类方法。

The way it is done in this example works, but it looks somehow weird to me, replacing the method with a call to the original method only to be able to put the decorator. Also, for this to work, the method needs to be defined as a classmethod in the parent class.

我错过了什么吗?有经验的开发人员将如何做到这一点?

Am I missing something? How would experienced developers do this?

任何帮助,见解,评论和免费咖啡都将受到赞赏!

Any help, insights, critical comments and free coffees are much appreciated!

推荐答案

您没有必须在装饰器语法中使用装饰器。这只是可调用的:

You don't have to use a decorator in decorator syntax. It is just a callable:

class Child(Person):
    def __init__(self, age):
        Person.__init__(self, age=age)

    gets_drink = dec(Person.gets_drink.__func__)

这会将装饰器的返回值作为具有相同名称的方法添加到子类中。 __ func __ 属性解开绑定(类)方法,检索原始函数。

This adds the return value of the decorator to the child class as a method with the same name. The __func__ attribute unwraps the bound (class) method, retrieving the original function.

请注意,您的新方法是现在是常规方法,而不是类方法,则必须在 classmethod()调用中重新包装结果。

Note that your new method is now a regular method, not a classmethod, you'd have to re-wrap the result in a classmethod() call for that.

之所以有效是因为语法

@decorator_expression
def function_definition():
    pass

仅仅是以下方面的语法糖:

is just syntactic sugar for:

def function_definition():
    pass
function_definition = decorator_expression(function_definition)

这篇关于在子类中如何装饰继承的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆