Python类的动态绑定实现原理


Posted in Python onMarch 21, 2020

使用实例引用类的属性时,会发生动态绑定。即python会在实例每次引用类属性时,将对应的类属性绑定到实例上。

动态绑定的例子:

class A:
  def test1(self):
    print("hello")
  
  def test2(self):
    print("world")

def bound():
  a = A()
  a.test1()
  A.test1 = A.test2
  a.test1()

if __name__ == "__main__":
  bound()

输出结果:

hello2 world

从上述代码中可以看到,类方法的变化是实时影响实例对方法的调用的,这说明python是在实例调用方法的过程中动态地查找类方法。

动态绑定的代价:

class A:
  def test(self):
    pass
def one_loop(limited_time):
  a = A()
  for i in range(limited_time):
    a.test()
  f = a.test
  for i in range(limited_time):
    f()

上图两个循环中,一个调用a.test(),不断进行动态绑定,另一个则先把a.test赋值给f,只有一次动态绑定,通过对两个循环计时,测试动态绑定的代价。

输出结果:

Python类的动态绑定实现原理

1 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0009999275207519531, 0.008995771408081055, 0.19991111755371094, 1.2715933322906494, 15.831915855407715]
2 [0.0, 0.0, 0.0, 0.0, 0.0, 0.12503726671039295, 0.09472344399590288, 0.1999776288967874, 0.131608969147562, 0.1553209370384522]

折线图中横坐标为log10(循环次数),纵坐标为秒数。

输出数据中,第一行为动态绑定和一次绑定耗费时间的差值,第二行为差值占动态绑定总时间的比例。

可以看出,在次数很小的时候,两者基本没有差距,或者说差距忽略不计。

在10^7次循环,即千万次循环的时候,动态绑定与静态绑定的耗费时间才出现了明显差异,当循环次数达到十亿级的时候,耗费时间相差15秒之多,约占总时间的15%。

由上可知,动态绑定效率低于静态绑定,但由于绑定代价耗时很少,在次数很少的时候基本没有影响。

动态绑定的优点:

class A:
  def test_hello(self):
    print("hello")

def test_world(self):
  print("world")

def main():
  s = A()
  # 提前绑定
  f = s.test_hello
  # 改变方法
  A.test_hello = test_world
  f()
  # 动态绑定
  s.test_hello()

if __name__ == "__main__":
  main()

输出结果:

hello2 world

类方法的变动能够实时反应在动态绑定上,而提前绑定则无法感知到类方法的变动。

总结:

1. 一次动态绑定代价很小,当绑定次数少的时候基本不影响效率,当绑定次数达到千万级时影响才会很显著。

2. 动态绑定实时跟踪类方法的变动,更具灵活性。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详解在Python程序中自定义异常的方法
Oct 16 Python
Python原始字符串与Unicode字符串操作符用法实例分析
Jul 22 Python
python 3.5实现检测路由器流量并写入txt的方法实例
Dec 17 Python
Python中一些不为人知的基础技巧总结
May 19 Python
python多进程读图提取特征存npy
May 21 Python
解决python中使用PYQT时中文乱码问题
Jun 17 Python
解决Pytorch 训练与测试时爆显存(out of memory)的问题
Aug 20 Python
python线程中的同步问题及解决方法
Aug 29 Python
Python进阶之迭代器与迭代器切片教程
Jan 29 Python
详解在Python中使用Torchmoji将文本转换为表情符号
Jul 27 Python
教你用python实现一个无界面的小型图书管理系统
May 21 Python
Python语言规范之Pylint的详细用法
Jun 24 Python
Python类和实例的属性机制原理详解
Mar 21 #Python
Python生成器常见问题及解决方案
Mar 21 #Python
Python作用域与名字空间原理详解
Mar 21 #Python
Python小整数对象池和字符串intern实例解析
Mar 21 #Python
Python描述符descriptor使用原理解析
Mar 21 #Python
Python如何省略括号方法详解
Mar 21 #Python
Python如何使用bokeh包和geojson数据绘制地图
Mar 21 #Python
You might like
php不使用插件导出excel的简单方法
2014/03/04 PHP
密码强度检测效果实现原理与代码
2013/01/04 Javascript
jsonp原理及使用
2013/10/28 Javascript
js控制iframe的高度/宽度让其自适应内容
2014/04/09 Javascript
jQuery formValidator表单验证
2016/01/07 Javascript
BootStrap轻松实现微信页面开发代码分享
2016/10/21 Javascript
JS身份证信息验证正则表达式
2017/06/12 Javascript
微信小程序实现轮播图效果
2017/09/07 Javascript
详解BootStrap表单验证中重置BootStrap-select验证提示不清除的坑
2019/09/17 Javascript
小程序中使用css var变量(使js可以动态设置css样式属性)
2020/03/31 Javascript
详解JS预解析原理
2020/06/16 Javascript
Nuxt配置Element-UI按需引入的操作方法
2020/07/06 Javascript
JavaScript 事件代理需要注意的地方
2020/09/08 Javascript
js实现随机点名功能
2020/12/23 Javascript
[01:07:20]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第二场 2月2日
2021/03/11 DOTA
Python装饰器的函数式编程详解
2015/02/27 Python
Python2.x与Python3.x的区别
2016/01/14 Python
Python3安装Scrapy的方法步骤
2017/11/23 Python
Python运行不显示DOS窗口的解决方法
2018/10/22 Python
Python爬虫之urllib基础用法教程
2019/10/12 Python
如何在mac环境中用python处理protobuf
2019/12/25 Python
详解Windows下PyCharm安装Numpy包及无法安装问题解决方案
2020/06/18 Python
Python实现扫码工具的示例代码
2020/10/09 Python
详解Pycharm第三方库的安装及使用方法
2020/12/29 Python
英国家庭家具、照明和花园家具购物网站:Furniture123
2018/12/31 全球购物
英国打印机墨盒销售网站:Ink Factory
2019/10/07 全球购物
有影响力的人、名人和艺术家的官方商品:Represent
2019/11/26 全球购物
播音主持女孩的自我评价分享
2013/11/20 职场文书
拓展培训心得体会
2014/01/04 职场文书
防沙治沙典型材料
2014/05/07 职场文书
群众路线学习心得体会范文
2014/11/05 职场文书
2014年客房服务员工作总结
2014/11/18 职场文书
教师求职自荐信范文
2015/03/04 职场文书
少先队大队委竞选口号
2015/12/25 职场文书
七年级英语教学反思
2016/02/15 职场文书
MySQL 自定义变量的概念及特点
2021/05/13 MySQL