标签:生命周期 处理 代码 产生 dict size sel nbsp except
一、说明
这个过程类似“打包”,在一些游戏开发场景中,常常有将函数延后执行或者需要将函数作为回调入参,这时函数需要带参就不好处理了。例如:
1 import Functor 2 3 sUser = ‘用户名‘ 4 iAcct = 123 5 sPass = ‘******‘ 6 7 def notify(sUser, bSuc): 8 if bSuc: 9 print sUser + ‘成功登录‘ 10 11 ‘‘‘login(iAcct, sPass, pfunCB)负责执行登录过程, 12 在结束时调用pfunCB(bSuc)通知登录结果 13 ‘‘‘ 14 pfunCB = Functor(notify, sUser) 15 login(iAcct, sPass, pfunCB)
上面是一个登录过程,Functor就是要实现的打包器,将notify(sUser, bSuc)打包为只需一个入参的pfunCB(bSuc)
二、python的方法相关知识
1.python的方法是对象
方法的调用实质上是调用方法实例的__call__(),
因此,把对象变为可调用项,只需添加__call__()。例:
1 class Fun(): 2 def __init__(self): 3 pass 4 5 def __call__(self, obj): 6 print obj 7 8 a = Fun() 9 a(67890) # 等同a.__call__(67890)
2.实例方法的关键属性
对于实例方法的函数对象,我们可以通过__func__或im_func属性获取原始的函数对象。
下面的例子中,Functor还引用了实例方法的实例对象,因为当实例被回收时,我们不希望再调用该实例的方法,需要兼容这种情况。当然,更合理的做法是在代码中规避这种用法,不合理的使用常常导致bug的产生。
可以通过__self__或im_self获取实例方法的实例对象,类方法也可以这样获取到类实例(注意类方法的类实例不是im_class属性)。
三、Functor的实现
=======================Functor.py=======================
1 # -*- coding:utf-8 -*- 2 3 import types 4 import weakref 5 6 class Functor(): 7 def __init__(self, _fn, *args, **kwargs): 8 if not callable(_fn): 9 raise Exception(‘object is unable to call‘) 10 11 if isinstance(_fn, types.MethodType): 12 # 实例方法,类方法 13 # 弱引用实例对象,使Functor不影响对象的生命周期 14 self.m_wrObj = weakref.ref(_fn.__self__) 15 self.m_Func = _fn.im_func 16 self.m_bIsMethodType = True 17 else: 18 # 非实例方法 19 self.m_wrObj = None 20 self.m_Func = _fn 21 self.m_bIsMethodType = False 22 23 self.m_args = args 24 self.m_kwargs = kwargs 25 26 def __call__(self, *args, **kwargs): 27 curkwargs = dict(self.m_kwargs) 28 curkwargs.update(kwargs) 29 if not self.m_bIsMethodType: 30 return self.m_Func(*(self.m_args + args), **kwargs) 31 else: 32 obj = self.m_wrObj() 33 if obj is None: 34 return None 35 return self.m_Func(*((obj,) + self.m_args + args), **kwargs) 36 37 #test len(‘abc‘) 38 len_no_arg = Functor(len, ‘abc‘) 39 print len_no_arg()
标签:生命周期 处理 代码 产生 dict size sel nbsp except
原文地址:https://www.cnblogs.com/fu-feng/p/13193355.html