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中让MySQL查询结果返回字典类型的方法
Aug 22 Python
python实现去除下载电影和电视剧文件名中的多余字符的方法
Sep 23 Python
python中map()函数的使用方法示例
Sep 29 Python
python绘制立方体的方法
Jul 02 Python
用python3教你任意Html主内容提取功能
Nov 05 Python
python挖矿算力测试程序详解
Jul 03 Python
python如何实现不用装饰器实现登陆器小程序
Dec 14 Python
Python如何存储数据到json文件
Mar 09 Python
Jupyter 无法下载文件夹如何实现曲线救国
Apr 22 Python
python如何写try语句
Jul 14 Python
python -v 报错问题的解决方法
Sep 15 Python
python如何将mat文件转为png
Jul 15 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写MySQL数据 实现代码
2009/06/15 PHP
PHP中strlen()和mb_strlen()的区别浅析
2014/06/19 PHP
php读取qqwry.dat ip地址定位文件的类实例代码
2016/11/15 PHP
php运行报错Call to undefined function curl_init()的最新解决方法
2016/11/20 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
thinkphp5+layui实现的分页样式示例
2019/10/08 PHP
Javascript Math对象
2009/08/13 Javascript
js判断是否为数组的函数: isArray()
2011/10/30 Javascript
Javascript Request获取请求参数如何实现
2012/11/28 Javascript
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
JavaScript中json使用自己总结
2013/08/13 Javascript
angularjs中的单元测试实例
2014/12/06 Javascript
AngularJS表单编辑提交功能实例
2015/02/13 Javascript
jQuery+easyui中的combobox实现下拉框特效
2015/02/27 Javascript
JavaScript中的Function函数
2015/08/27 Javascript
window.location.reload 刷新使用分析(去对话框)
2015/11/11 Javascript
Js利用Canvas实现图片压缩功能
2017/09/13 Javascript
Vue+Koa2+mongoose写一个像素绘板的实现方法
2019/09/10 Javascript
深入浅析python继承问题
2016/05/29 Python
浅谈python对象数据的读写权限
2016/09/12 Python
python3使用PyMysql连接mysql数据库实例
2017/02/07 Python
Python实现购物评论文本情感分析操作【基于中文文本挖掘库snownlp】
2018/08/07 Python
python中的split()函数和os.path.split()函数使用详解
2019/12/21 Python
python实现飞船游戏的纵向移动
2020/04/24 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
2020/05/25 Python
详解基于python的全局与局部序列比对的实现(DNA)
2020/10/07 Python
世界领先的26岁以下学生和青少年旅行预订网站:StudentUniverse
2018/07/01 全球购物
医学院护理专业应届生求职信
2013/11/12 职场文书
十八届三中全会个人学习材料
2014/02/13 职场文书
单位活动策划方案
2014/08/17 职场文书
我们的节日国庆活动方案
2014/08/19 职场文书
幼师辞职信怎么写
2015/02/27 职场文书
小学秋季运动会通讯稿
2015/11/25 职场文书
pycharm 如何查看某一函数源码的快捷键
2021/05/12 Python
MySQL注入基础练习
2021/05/30 MySQL