内容
1.通过实例方法名字的字符串调用方法
- 我们有三个图形类 Circle,Triangle,Rectangle
- 他们都有一个获取图形面积的方法,但是方法名字不同,我们可以实现一个统一的获取面积的函数,使用每种方法名进行尝试,调用相应类的接口
-
getattr(x,“y”,None) --> 等同于 x.y 当x中不含有y时,返回None
-
map(func,iterable) --> 将iterable中的元素一一映射到func函数中处理,并且返回新的map对象。
2. 垃圾回收机制
-
介绍
-
在Python程序运行的时候,会在内存中开辟一块空间,用于存放临时变量;当计算完成之后,就会将结果输出到永久性存储器中。如果数据量特别大,那内存空间管理不妥当的话就非常容易爆内存,程序可能直接终止。
-
在Python中,一切皆对象。所以,每一个变量,实际上都是对象的一个指针。所以,当这个对象的引用计数(指针数)为0的时候,说明它也变成了垃圾,需要被放到回收箱中。
-
OS模块
- 与操作系统交互的库
-
psutil模块
- 与系统交互的库,能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。它主要用来做系统监控,性能分析,进程管理。
-
通过以下代码检测程序在运行时的内存消耗
-
当a是局部变量时,在返回到函数调用处时,局部变量的引用会注销。这时,列表a所指代对象的引用数为0,Python便会执行垃圾回收,因此之前占用的内存被收回了。
- 当a是全局变量的时,即使函数体内代码执行完毕,返回到函数调用处时,对列表a的引用仍然是存在的,所以对象不会被垃圾回收,依然占有大量内存。
- 当a局部变量返回出去 也不会被回收
- Python内部的引用计数机制
- 我们可以通过sys.getrefcount()这个函数,来了解Python内部的引用计数机制。
-
getrefcount本身也会引入一次计数。
-
函数引用示范
- 手动启动垃圾回收
- 如果我们可以手动删除完对象的引用,然后强制调用gc.collect()清除没有引用的对象,其实也就是手动的启动对象的回收。
- 循环引用
- 如果有两个对象,它们互相引用,并且不再被别的对象所引用,那么它们应该被垃圾回收吗?
总而言之,当双向引用的时候,引用计数虽然还在,但我们可以手动拉起回收,进行释放内存。所以,引用次数是垃圾回收的 充分非必要条件。
-
调试内存泄漏
在Python中通过引用计数和垃圾回收来管理内存,但是在一定情况下也会产生内存泄露- 第一是对象被另一个生命周期特别长的对象所引用
- 第二是循环引用中的对象定义了__del__函数
-
objgraph,一个非常好用的可视化引用关系的包。在这个包中的 show_refs() ,它可以生成清晰的引用关系图。
.dot文件转图片:https://onlineconvertfree.com/zh/
-
用 cProfile 进行性能分析
-
除了要对程序进行调试,性能分析也是每个开发者的必备技能。
日常工作中,我们常常会遇到这样的问题:在线上,我发现产品的某个功能模块效率低下,延迟高,占用的资源多,但却不知道是哪里出了问题。
这时,对代码进行 profile 就显得异常重要了。
这里所谓的 profile,是指对代码的每个部分进行动态的分析,比如准确计算出每个模块消耗的时间等。 -
计算斐波拉契数列,运用递归思想
接下来,我想要测试一下这段代码总的效率以及各个部分的效率 -
参数介绍:
-
ncalls:函数被调用的次数。如果这一列有两个值,就表示有递归调用,第二个值是原生调用次数,第一个值是总调用次数。
-
tottime:函数内部消耗的总时间。(可以帮助优化)
-
percall:是tottime除以ncalls,一个函数每次调用平均消耗时间。
-
cumtime:之前所有子函数消费时间的累计和。
-
filename:lineno(function):被分析函数所在文件名、行号、函数名。
-
经典的参数错误