刚刚想起猴子布丁,查了点资料,自己实践了下,记录汇总下。
猴子补丁(monkey patch)的主要功能就是动态的属性和方法的替换(真的超级无节操)
因为Python是面向对象的编程,所以一切类,实例对象,导入的包都可以当做对象。
首相定义一个最简单的类:
class A(): pass
实例化a = A()
好了这个类A里面默认没有属性跟方法
实例a里面也没有任何的实例方法
首先我们可以对类A进行动手脚,对类A里面可以添加对象方法,类静态方法,类属性,(类方法暂时没发现如何添加)
外部定义几个简单的函数:
def c_func_add(x, y): return x + y def cs_func_multiply(self, x, y): return x * y def s_func_show(): print('i am add func')
In [103]: A.c_f = c_func_add In [104]: A.cs_f = cs_func_multiply In [106]: a = A() In [107]: a.s_f = s_func_show In [108]: A.c_f(1,2) Out[108]: 3 In [109]: a.cs_f(2,3) Out[109]: 6 In [110]: a.s_f() i am add func
整个执行过程中,在定义好类与实例对象后,在里面可以添加不同的方法,其实这里没实验,就是添加属性也是可以的,A.name='lala'或者a.name='haha',当输入后分别属于一个类属性,一个实例属性。
猴子布丁还有一个好处就是你在import不同的模块时比如module1,module2。
你可能就会用到module2里面的into方法,你直接可以通过module1.into = moddule2.into
module1里面如果本来就有定义的方法将回覆盖。
今天在学习Django中碰到了更加有意思的情况,在用到get_or_greate方法时,为了减少与数据库的交互查询,可以通过猴子布丁的方式,将查询结果先缓存到实例属性里面。
这个能够大大降低实际过程中数据库的交互。
if not hasattr(self, '_profile'): self._profile, _ = Profile.objects.get_or_create(id=self.id) return self._profile
高手老师那里学到了很多,记号,以免以后忘记