IDC

替换一个实例方法,没你想的那么简单

作者:admin 2021-04-12 我要评论

思路一:简单地替换 当你想对类实例的方法进行替换时,你可能想到的是直接对他进行粗暴地替换: classPeople: defspeak(self): print(hello,world) defspeak(sel...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

思路一:简单地替换

当你想对类实例的方法进行替换时,你可能想到的是直接对他进行粗暴地替换:

  1. class People: 
  2.     def speak(self): 
  3.         print("hello, world") 
  4.  
  5.  
  6. def speak(self): 
  7.     print("hello, python") 
  8.  
  9. p = People() 
  10. p.speak = speak 
  11. p.speak() 

但当你试着执行这段代码的时候,就会发现行不通,它提示我们要传入 self 参数:

  1. Traceback (most recent call last): 
  2.   File "/Users/MING/Code/Python/demo.py", line 12, in <module> 
  3.     p.speak() 
  4. TypeError: speak() missing 1 required positional argument: 'self' 

不对啊~ self 不是实例本身吗?函数不是一直就这么写的?

实际上你这么替换,speak 就变成了一个 function,而不是一个和实例绑定的 method ,你可以把替换前后的 speak 打印出来

  1. p = People() 
  2. print(p.speak) 
  3. p.speak = speak 
  4. print(p.speak) 

输出结果如下,区别非常明显

  1. <bound method People.speak of <__main__.People object at 0x10cfa7fd0>> 
  2. <function speak at 0x10ca10040> 

这种方法,只能用在替换不与实例绑定的静态方法上,不然你每次调用的时候,就得手动传入实例本身,但这样调用就会变得非常怪异。

思路二:利用 im_func

有 Python 2 使用经验的朋友,可以会知道类实例的方法,都有 im_func 和 im_class 属性,分别指向了该方法的函数和类。

很抱歉的是,这些在 Python3 中全都取消了,意味你无法再使用 im_func 和 im_class 。

但即使你身处 Python 2 的环境下,你想通过 im_func 去直接替换函数,也仍然是有问题的。

因为在 Python2 中不推荐普通用户对类实例的方法进行替换,所以 Python 给类实例的方法赋予了只读属性

思路三:非常危险的字节码替换

表层不行,但这个方法在字节码层面却是可行的

这种方法,非常的粗暴且危险,他会直接影响到使用 People 的所有实例的 speak 方法,因此这种方法千万不要使用。

思路四:利用 types 绑定方法

在 types 中有一个 MethodType,可以将普通方法与实例进行绑定。

绑定后,就可以直接替换掉原实例的 speak 方法了,完整代码如下:

  1. import types 
  2.  
  3. class People: 
  4.     def speak(self): 
  5.         print("hello, world") 
  6.  
  7.  
  8. def speak(self): 
  9.     print("hello, python") 
  10.  
  11. p = People() 
  12. p.speak = types.MethodType(speak, p) 
  13. p.speak() 

这种方法,最为安全,不会影响其他实例。并且 Python 2 和 Python 3 都适用,是官方推荐的一种做法。

总结一下

  • 直接替换:只适用于静态方法
  • 使用 im_func 替换:行不通
  • 使用 im_func.func_code 替换字节码:非常危险,请不要使用
  • 使用 types.MethodType 进行方法绑定:安全且有效,推荐使用

本文转载自网络,原文链接:http://mp.weixin.qq.com/s?__biz=MzIzMzMzOTI3Nw==&mid=2247498810&idx=1&sn=56c70029002681fd72f14443e467c225&chksm=e8859cd8dff215ce7fe730e16edc1e0c0956bed312975f3fcf497376ee3f1e31f29d028ca704&mpshare=1&s

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • 太棒了!Python和Excel过了这么久终于

    太棒了!Python和Excel过了这么久终于

  • Java编程内功-数据结构与算法「线索化

    Java编程内功-数据结构与算法「线索化

  • 在Java中使用异步编程

    在Java中使用异步编程

  • Kafka性能篇:为何Kafka这么&quot;

    Kafka性能篇:为何Kafka这么&quot;

腾讯云代理商
海外云服务器