返回 lambda 函数与返回 python 装饰器中的方法的区别

Difference of returning a lambda function vs returning a method in python decorator

我试图了解在下面的装饰器中返回 lambda 与方法的区别。调用对象实例 "o" 丢失,并且在返回 m.fm 时未被装饰器传递。装饰器将在返回 lambda 函数的同时传递实例。是否可以通过装饰器中的返回方法传递调用对象?

def deco(*type):
    def wrapper(func):
        m = M()
        # return lambda callingobj, *args: m.fm(callingobj, *args)
        return m.fm
    return wrapper

class M(object):
    def fm(self, callingobj, *args):
        print(f'self_ {callingobj}, args {args}')

class O(object):
    @deco('int')
    def fo(self, *args):
        print(f'{args}')


o = O()
o.fo(1, 2, 3)

输出:

  1. return lambda callingobj, *args: m.fm(callingobj, *args)

    callingobj <__main__.O object at 0x000002453BE95760>, args (1, 2, 3)

  2. return m.fm

    callingobj 1, args (2, 3)

使用 lambda 表达式,属性 O.fo 绑定到 function 对象。访问时,o.fo 生成 O.fo.__get__(o, O) 的值,这是一个 method 对象,将其参数传递给函数。也就是说,__get__ returns 一个函数,其第一个参数是 callingobj,它绑定到 o。其余参数绑定为元组 (1, 2, 3) toargs`

使用return m.fm,属性O.fo绑定到m.fm产生的method对象,相当于M.fm.__get__(m, M)。重要的是,method 对象没有 __get__ 方法,所以 o.fo 直接给你 M class 的方法。 现在 参数 123 被赋值,因此 1 被赋值给 callingobj(2, 3)分配给 args.

换句话说,不同之处在于某些函数的 __get__ 方法相对于处理 o.fo 的参数的顺序。