Python基础教程:__call__用法
人生苦短,我用python
python 安装包+资料:点击此处跳转文末名片获取
__call__
可以使得方法变成可被调用对象;
(PS:python中的方法和普通函数有点区别:
方法的第一个参数是类实例)
允许一个类的实例像函数一样被调用。
实质上说,
这意味着 x()
与 x.__call__()
是相同的。
注意__call__
参数可变。
这意味着你可以定义__call__
为其他你想要的函数,
无论有多少个参数。
class Entity:
'''调用实体来改变实体的位置'''def _init_(self,size,x,y):self.x,self.y = x,yself.size = size
def _call_(self,x,y):'''改变实体的位置'''self.x, self.y = x,ye = Entity(1,2,3)#创建实例
e(4,5)#实例可以像函数那样执行,并传入x y值,修改对象的x y
实例对象也可以像函数一样作为可调用对象来用,
那么,
这个特点在什么场景用得上呢?
这个要结合类的特性来说,
类可以记录数据(属性),
而函数不行(闭包某种意义上也可行),
利用这种特性可以实现基于类的装饰器,
在类里面记录状态,
比如,下面这个例子用于记录函数被调用的次数:
class Counter:def _init_(self,func):self.func = funcself.count = 0def _call_(self,*args,kwargs):self.count += 1return self.func(*args,kwargs)@Counter
def foo():pass
for i in range(10):foo()print(foo.count) #10
首先这里的@Counter
是装饰器,
执行起来顺序是 foo = Counter(foo)
,
实例化,把foo函数传到类Counter里面,
并存到对象属性里面,
然后返回foo = Counter
实例。
这时foo
已经是Counter
实例,
而不是本身foo
函数。
PS:__call__这种用法在pytorch中也有所体现,pytorch中自定义的类继承于nn.Module父类,且该子类中对父类的forward方法进行了重载,且父类nn.Module中的__call__中调用了forward方法,所以我们直接用子类的实例作为可调用对象
👇问题解答 · 源码获取 · 技术交流 · 抱团学习请联系名片👇