内容
1. 如何派生内置不可变类型并修改其实例化行为
- 回顾__new__
- __new__方法是创建对象的方法
- 1.此处重写了父类的方法
- 2.需调用父类的__new__方法创建对象
- 3.需将对象返回出来给__init__方法
2. 如何为创建大量实例节省内存
练习需求
在游戏开发中,有一个玩家类Player,每有一个在线玩家,在服务器内则有一个player的实例,当在线的人数很多时,将产生大量实例(百万级)
如何降低这些大量实例的内存开销?
解决方案:定义类的 _ _ slots _ _ 属性,声明实例有哪些属性(关闭动态绑定)
- 使用 _ _ dict _ _字典主要是为了提升查询效率,所以必须使用空间换时间
- 少量的实例,使用字典存储,问题不大。但如果像我们的业务达到数百万个实例,字典占用的总空间就比较大。
- 这个 _ _ slots _ _ 相当于告诉解释器,实例的属性都叫什么。而且既然需要节省内存,推荐定义时使用元组,而不是列表。
- _ _ slots _ _是否会继承?
- _ _ slots _ _不影响子类实例,不会继承,除非子类里面自己定义了
3. 上下文管理器
- python中的with语句
- 自定义类使用上下文管理器
- with语句处理对象必须有 _ _ enter _ _ 方法及 _ _ exit _ 方法。并且 _ _ enter_ _ _ 方法在语句体(with语句包括起来的代码块)执行之前进入运行, _ _ exit _ _ 方法在语句体执行完毕退出后自动运行。
- contextlib简化上下文管理器
4.如何创建可管理的对象属性
-
在面向对象编程中,我们把方法看作对象的接口。直接访问对象的属性可能是不安全的,或设计上不够灵活,但是使用调用方法在形式上不如直接访问属性简洁。
-
实现需求:
5. 如何让类支持比较操作
- 有时我们希望自定义类的实例间可以使用,<,<=,>,>=,==,!=符号进行比较,我们自定义比较的行业,例如,有一个矩形的类,比较两个矩形的实例时,比较的是他们的面积
- @total_ordering装饰器就只需要完成__ge__与__gt__两个方法 就可以全部实现
6. 如何在环状数据结构中管理内存
- 在python中,垃圾回收器通过引用计数来回收垃圾对象,当一个对象引用计数为0,或者只剩下弱引用时,这个对象会被释放。
计数为0时
- 弱引用
- 弱引用不增加引用计数,使用弱引用访问对象得到对象引用
-
双链表
-
变量head指向节点1,节点1右引用节点2,节点2右引用节点3。节点3左弱引用节点2,节点2左弱引用节点1。
-
当变量head指向None时,节点1对象被释放,节点1的右引用节点2被释放,节点2的右引用节点3被释放。