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中的WSGI接口
May 11 Python
使用Python3 编写简单信用卡管理程序
Dec 21 Python
Python错误: SyntaxError: Non-ASCII character解决办法
Jun 08 Python
python随机数分布random测试
Aug 27 Python
[原创]Python入门教程2. 字符串基本操作【运算、格式化输出、常用函数】
Oct 29 Python
python将控制台输出保存至文件的方法
Jan 07 Python
Python和Go语言的区别总结
Feb 20 Python
Python button选取本地图片并显示的实例
Jun 13 Python
python pygame实现滚动横版射击游戏城市之战
Nov 25 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
Feb 24 Python
python 实现简易的记事本
Nov 30 Python
一个非常简单好用的Python图形界面库(PysimpleGUI)
Dec 28 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小技巧之过滤ascii控制字符
2014/05/14 PHP
CentOS下搭建PHP环境与WordPress博客程序的全流程总结
2016/05/07 PHP
PHP Mysqli 常用代码集合
2016/11/12 PHP
用PHP的socket实现客户端到服务端的通信实例详解
2017/02/04 PHP
PHP Primary script unknown 解决方法总结
2019/08/22 PHP
javascript编程起步(第五课)
2007/02/27 Javascript
Tips 带三角可关闭的文字提示
2010/10/06 Javascript
深入理解JavaScript系列(3) 全面解析Module模式
2012/01/15 Javascript
文本框倒叙输入让输入框的焦点始终在最开始的位置
2014/09/01 Javascript
jQuery模仿京东/天猫商品左侧分类导航菜单效果
2016/06/29 Javascript
JavaScript实现按键精灵的原理分析
2017/02/21 Javascript
微信小程序 wx:for的使用实例详解
2017/04/27 Javascript
jQuery Validate 校验多个相同name的方法
2017/05/18 jQuery
vue axios 给生产环境和发布环境配置不同的接口地址(推荐)
2018/05/08 Javascript
pytyon 带有重复的全排列
2013/08/13 Python
Python对文件和目录进行操作的方法(file对象/os/os.path/shutil 模块)
2017/05/08 Python
基于Python os模块常用命令介绍
2017/11/03 Python
使用 Python 实现简单的 switch/case 语句的方法
2018/09/17 Python
详解Python3 pickle模块用法
2019/09/16 Python
python自动分箱,计算woe,iv的实例代码
2019/11/22 Python
Pytorch之view及view_as使用详解
2019/12/31 Python
Windows下python3安装tkinter的问题及解决方法
2020/01/06 Python
Python程序控制语句用法实例分析
2020/01/14 Python
Python 简单计算要求形状面积的实例
2020/01/18 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
2020/03/20 Python
如何用python爬取微博热搜数据并保存
2021/02/20 Python
园林资料员岗位职责
2013/12/30 职场文书
初二政治教学反思
2014/01/12 职场文书
高中竞选班长演讲稿
2014/04/24 职场文书
班级出游活动计划书
2014/08/15 职场文书
python实现web邮箱扫描的示例(附源码)
2021/03/30 Python
React配置子路由的实现
2021/06/03 Javascript
nginx中proxy_pass各种用法详解
2021/11/07 Servers
MYSQL 运算符总结
2021/11/11 MySQL
如何更改Win11声音输出设备?Win11声音输出设备四种更改方法
2022/04/08 数码科技
Python采集壁纸并实现炫轮播
2022/04/30 Python