《Python学习笔记》的笔记
16/Mar 2013
这是对雨痕写的Python学习笔记的学习。
基本环境
对象总是按引用用传递,简单点说就是通过复制指针来实现多个名字指向同一一对象。
因为 arena 也是在堆上分配的,所以无无论何种类型何种大大小小的对象,都存储在堆上。Python 没有值类型和引用用类型一一说,就算是最简单的整数也是拥有标准头的完整对象。
引用计数
除了直接引用用外,Python还支支持弱引用用。允许在不增加引用用计数,不妨碍对象回收的情况下间接引用用对象。但不是所有类型都支支持弱引用用,比比如 list、dict ,弱引用用会引发异常。
垃圾回收
Python 拥有两套垃圾回收机制。除了引用计数,还有个专⻔门处理循环引用的 GC。通常我们提到垃圾回收时,都是指这个 «Reference Cycle Garbage Collection»。
能引发循环引用用问题的,都是那种容器类对象,比比如 list、set、object 等。对于这类对象,虚拟机在为其分配内存时,会额外添加用用于追踪的PyGC_Head。这些对象被添加到特殊链表里里,以便GC 进行行管理。 如果不存在循环引用,自然是积极性更高的引用计数机制抢先给处理掉。也就是说,只要不存在循环引用,理论上可以禁用GC。当执行行某些密集运算时,临时关掉GC有助于提升性能。
#世代回收
内置类型
- 尽量使用xrange代替range,每次迭代后,数字对象被回收,其占用用内存空闲出来并被复用用,内存也就不会暴涨了。
字符串
>>> ",".join(["a", "b", "c"])
'a,b,c'
>>> "a,b,c".split(",")
!
['a', 'b', 'c']
>>> "a\nb\r\nc".splitlines()
['a', 'b', 'c']
>>>"a\nb\r\nc".splitlines(True)
['a\n', 'b\r\n', 'c']
>>> "abc".startswith("ab"), "abc".endswith("bc")
True, True
>>> "abc".upper(), "Abc".lower()
'ABC', 'abc'
>>> "abcabc".find("bc"), "abcabc".find("bc", 2) # 可指定查找起始结束位置。
1, 4
>>> " abc".lstrip(), "abc ".rstrip(), " abc ".strip() # 剔除前后空格。
'abc', 'abc', 'abc'
>>> "abc".strip("ac") # 可删除指定的前后缀字符。
'b'
>>> "abcabc".replace("bc", "BC")# 可指定替换次数。
'aBCaBC'
>>> "a\tbc".expandtabs(4)
'a bc'
>>> "123".ljust(5, '0'), "456".rjust(5, '0'), "abc".center(10, '*') # 填充
'12300', '00456', '***abc****'
>>> "123".zfill(6), "123456".zfill(4) # 数字填充
'000123', '123456'
string.Template可以处理较复杂的需求
池化
池化有助于减少对象数量和内存消耗,提升性能。用 intern() 函数可以把运行期动态生成的字符串池化。
List
可用bisect 向有序列表中插入元素。
性能
1. 列表用realloc()调整指针数组内存大小,可能需要复制数据。插入和删除操作,还会循环移动后续元素。这些都是潜在的性能隐患。对于频繁增删元素的大型列表,应该考虑用用链表等数据结构代替。
2. 某些时候,可以考虑用数组代替列表。和列表存储对象指针不同,数组直接内嵌数据,既省了创建对象的内存开销,又提升了读写效率。
###tuple
在编码中,应该尽可能用用元组代替列表。除内存复用更高效外,其只读特征更利于并行开发。
###dict
字典 (dict) 采用用开放地址法的哈希表实现。
• 自带元素容量为 8 的 smalltable,只有 «超出»时才到堆上额外分配元素表内存。
• 虚拟机缓存 80 个字典复用对象,但在堆上分配的元素表内存会被释放。
• 按需动态调整容量。扩容或收缩操作都将重新分配内存,重新哈希。
• 删除元素操作不会立立即收缩内存。
对于大字典,调用 keys()、values()、items() 会构造同样巨大的列表。建议用用迭代器替代,以减
少内存开销。
视图
要判断两个字典间的差异,使用用视图是最简便的做法。
>>> d1 = dict(a = 1, b = 2)
>>> d2 = dict(b = 2, c = 3)
>>> d1 & d2 # 字典不支支持该操作。
TypeError: unsupported operand type(s) for &: 'dict' and 'dict'
>>> v1 = d1.viewitems()
>>> v2 = d2.viewitems()
>>> v1 & v2 # 交集
set([('b', 2)])
>>> v1 | v2 #并
set([('a', 1), ('b', 2), ('c', 3)])
>>> v1 - v2 # 差集 (仅 v1 有,v2 没有的)
set([('a', 1)])
>>> v1 ^ v2 #对称差集 (不会同时出现在 v1 和 v2 中)
set([('a', 1), ('c', 3)])
>>> ('a', 1) in v1
True
set
集合 (set) 用来存储无序不重复对象。所谓不重复对象,除了不是同一对象外,还包括 «值» 不能相同。集合只能存储可哈希对象,一样有只读版本 frozenset。
运算: ==, !=, >, |, & ,-, ^
数据结构很重要,这几个内置类型并不足以完成全部工作。像 C、数据结构、常用算法这类基础是每个程序开发人员都应该掌握的。