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中http请求方法库汇总
Jan 06 Python
Python2.7简单连接与操作MySQL的方法
Apr 27 Python
利用Python如何生成hash值示例详解
Dec 20 Python
Python实现的简单排列组合算法示例
Jul 04 Python
python2 与 pyhton3的输入语句写法小结
Sep 10 Python
使用Django连接Mysql数据库步骤
Jan 15 Python
Python寻找路径和查找文件路径的示例
Jul 10 Python
Django xadmin开启搜索功能的实现
Nov 15 Python
Python浮点数四舍五入问题的分析与解决方法
Nov 19 Python
python实现ssh及sftp功能(实例代码)
Mar 16 Python
Python用摘要算法生成token及检验token的示例代码
Dec 01 Python
用Python制作音乐海报
Jan 26 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
收音机史话 - 1960年代前后的DIY
2021/03/02 无线电
PHP 字符截取 解决中文的截取问题,不用mb系列
2009/09/29 PHP
php面向对象全攻略 (十四) php5接口技术
2009/09/30 PHP
php版微信自动登录并获取昵称的方法
2016/09/23 PHP
php利用fsockopen GET/POST提交表单及上传文件
2017/05/22 PHP
详解php中的implements 使用
2017/06/13 PHP
关于laravel 日志写入失败问题汇总
2019/10/17 PHP
理解Javascript_12_执行模型浅析
2010/10/18 Javascript
有关DOM元素与事件的3个谜题
2010/11/11 Javascript
jQuery实现切换页面布局使用介绍
2011/10/09 Javascript
jquery 根据name名获取元素的value值
2015/02/27 Javascript
JavaScript给url网址进行encode编码的方法
2015/03/18 Javascript
jQuery标签编辑插件Tagit使用指南
2015/04/21 Javascript
jfinal与bootstrap的登录跳转实战演习
2015/09/22 Javascript
JS设置下拉列表框当前所选值的方法
2015/12/22 Javascript
JavaScript实现公历转农历功能示例
2017/02/13 Javascript
JavaScript的继承实现小结
2017/05/07 Javascript
浅谈ES6 模板字符串的具体使用方法
2017/11/07 Javascript
详解Vue.js使用Swiper.js在iOS
2018/09/10 Javascript
async/await优雅的错误处理方法总结
2019/01/30 Javascript
微信小程序位置授权处理方法
2019/06/13 Javascript
微信小程序实现购物车代码实例详解
2019/08/29 Javascript
javascript实现摄像头拍照预览
2019/09/30 Javascript
vuecli3.x中轻松4步带你使用tinymce的步骤
2020/06/25 Javascript
简单掌握Python的Collections模块中counter结构的用法
2016/07/07 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
解决python字典对值(值为列表)赋值出现重复的问题
2019/01/20 Python
Python 函数绘图及函数图像微分与积分
2019/11/20 Python
美国职棒大联盟的官方手套、球和头盔:Rawlings
2020/02/15 全球购物
生日邀请函范文
2014/01/13 职场文书
党支部组织生活会整改方案
2014/09/30 职场文书
入股协议书范本
2014/11/01 职场文书
4S店销售内勤岗位职责
2015/04/13 职场文书
关于五一放假的通知
2015/08/18 职场文书
尝试使用Python爬取城市租房信息
2022/04/12 Python
Python如何加载模型并查看网络
2022/07/15 Python