lambda - 返回 lambda 函数与在 python 装饰器中返回方法的区别
问题描述
我试图了解在下面的装饰器中返回 lambda 与方法的区别。返回 m.fm 时,调用对象实例“o”丢失且未由装饰器传递。装饰器将在返回 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)
输出:
和
return lambda callingobj, *args: m.fm(callingobj, *args)
callingobj <__main__.O object at 0x000002453BE95760>, args (1, 2, 3)
和
return m.fm
callingobj 1, args (2, 3)
解决方案
使用 lambda 表达式,属性O.fo
绑定到一个function
对象。访问时,o.fo
产生 的值O.fo.__get__(o, O)
,这是一个method
将其参数传递给函数的对象。也就是说,__get__
返回一个函数,其第一个参数是callingobj
,它被绑定到o
。其余参数绑定为元组(1, 2, 3) to
args`
使用return m.fm
,属性O.fo
绑定到由method
产生的对象m.fm
,相当于M.fm.__get__(m, M)
。重要的是,一个method
对象没有__get__
方法,所以直接o.fo
给你M
类的方法。现在,参数1
,2
和3
被分配,使得 1 被分配给callingobj
并且(2, 3)
被分配给args
。
换句话说,区别在于某些函数的__get__
方法相对于o.fo
处理参数的顺序。
推荐阅读
- python - Numpy 数组到 PIL 图像格式
- python - 如何进行酸洗以使其能够抵抗崩溃?
- javascript - jquery - 下拉选择上的功能问题
- android - Flutter 与现有应用程序崩溃
- android - 无法解析“:app@debug/compileClasspath”的依赖关系:无法解析 com.google.android.gms:play-services-basement:[15.0.0,16.0.0)
- c - printf %i 在这种情况下如何工作?
- google-cloud-platform - 将文件夹从 VM gcp 复制到本地计算机
- kubernetes - 如何将 Google 负载均衡器配置为在我的 Kubernetes yaml 中拥有 IPv4 和 IPv6 前端?
- css - Safari 无法使用引导导航
- node.js - GET http://localhost: 邮递员