当你想对类实例的方法进行替换时,你可能想到的是直接对他进行粗暴地替换:
公司主营业务:成都网站制作、网站设计、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联公司是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联公司推出孟州免费做网站回馈大家。
- class People:
- def speak(self):
- print("hello, world")
- def speak(self):
- print("hello, python")
- p = People()
- p.speak = speak
- p.speak()
但当你试着执行这段代码的时候,就会发现行不通,它提示我们要传入 self 参数:
- Traceback (most recent call last):
- File "/Users/MING/Code/Python/demo.py", line 12, in
- p.speak()
- TypeError: speak() missing 1 required positional argument: 'self'
不对啊~ self 不是实例本身吗?函数不是一直就这么写的?
实际上你这么替换,speak 就变成了一个 function,而不是一个和实例绑定的 method ,你可以把替换前后的 speak 打印出来
- p = People()
- print(p.speak)
- p.speak = speak
- print(p.speak)
输出结果如下,区别非常明显
>
这种方法,只能用在替换不与实例绑定的静态方法上,不然你每次调用的时候,就得手动传入实例本身,但这样调用就会变得非常怪异。
思路二:利用 im_func
有 Python 2 使用经验的朋友,可以会知道类实例的方法,都有 im_func 和 im_class 属性,分别指向了该方法的函数和类。
很抱歉的是,这些在 Python3 中全都取消了,意味你无法再使用 im_func 和 im_class 。
但即使你身处 Python 2 的环境下,你想通过 im_func 去直接替换函数,也仍然是有问题的。
因为在 Python2 中不推荐普通用户对类实例的方法进行替换,所以 Python 给类实例的方法赋予了只读属性
表层不行,但这个方法在字节码层面却是可行的
这种方法,非常的粗暴且危险,他会直接影响到使用 People 的所有实例的 speak 方法,因此这种方法千万不要使用。
在 types 中有一个 MethodType,可以将普通方法与实例进行绑定。
绑定后,就可以直接替换掉原实例的 speak 方法了,完整代码如下:
- import types
- class People:
- def speak(self):
- print("hello, world")
- def speak(self):
- print("hello, python")
- p = People()
- p.speak = types.MethodType(speak, p)
- p.speak()
这种方法,最为安全,不会影响其他实例。并且 Python 2 和 Python 3 都适用,是官方推荐的一种做法。
分享标题:替换一个实例方法,没你想的那么简单
标题路径:http://www.shufengxianlan.com/qtweb/news2/202602.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联