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代码来解图片迷宫的方法整理
Apr 02 Python
Python用Bottle轻量级框架进行Web开发
Jun 08 Python
Django基础知识与基本应用入门教程
Jul 20 Python
Python双向循环链表实现方法分析
Jul 30 Python
python读取当前目录下的CSV文件数据
Mar 11 Python
Python参数传递机制传值和传引用原理详解
May 22 Python
opencv 实现特定颜色线条提取与定位操作
Jun 02 Python
Python建造者模式案例运行原理解析
Jun 29 Python
TensorFlow Autodiff自动微分详解
Jul 06 Python
python接口自动化之ConfigParser配置文件的使用详解
Aug 03 Python
Django返回HTML文件的实现方法
Sep 17 Python
Python中的min及返回最小值索引的操作
May 10 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中extract()函数的妙用分析
2012/07/11 PHP
全面解读PHP的人气开发框架Laravel
2015/10/15 PHP
深入浅析php json 格式控制
2015/12/24 PHP
Zend Framework分页类用法详解
2016/03/22 PHP
php版微信小店调用api示例代码
2016/11/12 PHP
PHP+MySQL实现消息队列的方法分析
2018/05/09 PHP
yii2的restful api路由实例详解
2019/05/14 PHP
纯js实现的论坛常用的运行代码的效果
2008/07/15 Javascript
js报错 Object doesn't support this property or method的原因分析
2011/03/31 Javascript
js实现图片放大缩小功能后进行复杂排序的方法
2012/11/08 Javascript
JavaScript中instanceof与typeof运算符的用法及区别详细解析
2013/11/19 Javascript
JS替换文本域内的回车示例
2014/02/18 Javascript
jQuery焦点图切换简易插件制作过程全纪录
2014/08/27 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
socket.io学习教程之基本应用(二)
2017/04/29 Javascript
jQuery实现腾讯信用界面(自制刻度尺)样式
2017/08/15 jQuery
微信小程序实现手势图案锁屏功能
2018/01/30 Javascript
跨域解决之JSONP和CORS的详细介绍
2018/11/21 Javascript
JS实现点击生成UUID的方法完整实例【基于jQuery】
2019/06/12 jQuery
scrapyd schedule.json setting 传入多个值问题
2019/08/07 Javascript
Python中使用gzip模块压缩文件的简单教程
2015/04/08 Python
使用Python的Twisted框架编写简单的网络客户端
2015/04/16 Python
在python3中使用shuffle函数要注意的地方
2020/02/28 Python
python转化excel数字日期为标准日期操作
2020/07/14 Python
python爬虫工具例举说明
2020/11/30 Python
使用Python爬取小姐姐图片(beautifulsoup法)
2021/02/11 Python
基于第一个PhoneGap(cordova)的应用详解
2013/05/03 HTML / CSS
TripAdvisor德国:全球领先的旅游网站
2017/12/07 全球购物
TUMI香港官网:国际领先的行李箱、背囊品牌
2021/03/01 全球购物
大学专科自荐信
2014/06/17 职场文书
毕业生个人自荐书
2015/03/05 职场文书
幼儿园大班教育随笔
2015/08/14 职场文书
2015年党风廉政建设个人总结
2015/08/18 职场文书
电力培训学习心得体会
2016/01/11 职场文书
Redis中一个String类型引发的惨案
2021/07/25 Redis
Python NumPy灰度图像的压缩原理讲解
2021/08/04 Python