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编写类UNIX系统的命令行工具的教程
Apr 15 Python
在Django的视图(View)外使用Session的方法
Jul 23 Python
python Django批量导入不重复数据
Mar 25 Python
利用pyinstaller或virtualenv将python程序打包详解
Mar 22 Python
Python3.遍历某文件夹提取特定文件名的实例
Apr 26 Python
利用selenium爬虫抓取数据的基础教程
Jun 10 Python
Python切图九宫格的实现方法
Oct 10 Python
python同义词替换的实现(jieba分词)
Jan 21 Python
Python使用PyQt5/PySide2编写一个极简的音乐播放器功能
Feb 07 Python
Python如何通过百度翻译API实现翻译功能
Apr 02 Python
解决Keras 中加入lambda层无法正常载入模型问题
Jun 16 Python
python time.strptime格式化实例详解
Feb 03 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
Windows下的PHP5.0安装配制详解
2006/09/05 PHP
php数据结构 算法(PHP描述) 简单选择排序 simple selection sort
2011/08/09 PHP
Yii2实现增删改查后留在当前页的方法详解
2017/01/13 PHP
Javascript简单实现可拖动的div
2013/10/22 Javascript
js关于字符长度限制的问题示例探讨
2014/01/24 Javascript
与Math.pow 相反的函数使用介绍
2014/08/04 Javascript
js中数组排序sort方法的原理分析
2014/11/20 Javascript
jQuery中on()方法用法实例详解
2015/02/06 Javascript
Vue.js每天必学之内部响应式原理探究
2016/09/07 Javascript
jquery实现左右滑动式轮播图
2017/03/02 Javascript
angular+bootstrap的双向数据绑定实例
2017/03/03 Javascript
Vue写一个简单的倒计时按钮功能
2018/04/20 Javascript
微信小程序实现倒计时调用相机自动拍照功能
2018/06/10 Javascript
详解Angular5/Angular6项目如何添加热更新(HMR)功能
2018/10/10 Javascript
巧妙运用v-model实现父子组件传值的方法示例
2019/04/07 Javascript
vue发送websocket请求和http post请求的实例代码
2019/07/11 Javascript
构建大型 Vue.js 项目的10条建议(小结)
2019/11/14 Javascript
Vue+abp微信扫码登录的实现代码示例
2020/01/06 Javascript
vue@cli3项目模板怎么使用public目录下的静态文件
2020/07/07 Javascript
Python最火、R极具潜力 2017机器学习调查报告
2017/12/11 Python
Python实现屏幕截图的两种方式
2018/02/05 Python
用pandas按列合并两个文件的实例
2018/04/12 Python
python的scikit-learn将特征转成one-hot特征的方法
2018/07/10 Python
详解django实现自定义manage命令的扩展
2019/08/13 Python
python pycharm最新版本激活码(永久有效)附python安装教程
2020/09/18 Python
opencv python如何实现图像二值化
2020/02/03 Python
探秘TensorFlow 和 NumPy 的 Broadcasting 机制
2020/03/13 Python
Python字符串的15个基本操作(小结)
2021/02/03 Python
canvas进阶之如何画出平滑的曲线
2018/10/15 HTML / CSS
汉语专业毕业生自荐信
2014/07/06 职场文书
团队拓展活动总结
2014/08/27 职场文书
个人批评与自我批评材料
2014/10/17 职场文书
临时用工协议书范本
2014/10/29 职场文书
辞职信标准格式
2015/02/27 职场文书
中国现代文学之经典散文三篇
2019/09/18 职场文书
详解SpringBoot异常处理流程及原理
2021/06/21 Java/Android