使用类方法装饰类方法

时间:2014-07-26 12:21:45

标签: python decorator

我正在用另一个类方法装饰一个类方法。该课程看起来像这样

from functools import wraps

class MyClass(object):
    def __init__(self):
        print('Within my class object')

    def my_decorator(func_to_decorate):
        @wraps(func_to_decorate)
        def wrapper(self):
            print('Before the call')

            func_to_decorate(self)

            print('After the function call')
        return wrapper

    @my_decorator
    def print_name(self):
        print('My name is ------ ')

mobj = MyClass()
mobj.print_name()

工作正常我得到了我需要的输出

Before the call
My name is ------ 
After the function call

然后在查看装饰器my_decorator的函数定义时,我意识到该方法没有采用类方法通常采用的第一个参数self

我现在的问题是 - my_decorator的类型是什么?它是一种类方法,常规方法还是一种特殊方法?

通常,类中的方法采用隐式参数self,或者它的类方法采用隐式参数cls。装饰者没有拿走它们。

有人可以解释一下这里发生了什么吗?

1 个答案:

答案 0 :(得分:1)

这是一个简单的函数,因为您没有从类或实例访问它,因此在类定义中作为装饰器使用时,该函数不需要selfcls。只有当我们使用类或实例访问它们时,这些函数才强制使用隐式参数,因为通过类或实例访问它们会返回未绑定和绑定的方法,这些方法是原始函数周围的瘦包装器。

如果你将装饰器移到课外,那么你会发现它希望你发送一个实例作为第一个参数:

MyClass.print_name = MyClass.my_decorator(MyClass.print_name)
mobj = MyClass()
mobj.print_name()

错误:

MyClass.print_name = MyClass.my_decorator(MyClass.print_name)
TypeError: unbound method my_decorator() must be called with MyClass instance as first argument (got instancemethod instance instead)

虽然您可以通过将my_decorator声明为不需要selfcls的静态方法或使用绑定的im_func属性访问基础函数来阻止此错误,但不绑定对象:

MyClass.print_name = MyClass.my_decorator.im_func(MyClass.print_name)

您应该阅读data model页上的可调用类型部分。