内存管理
- 变量无需事先声明,也不需要指定类型,这是动态语言的特性
- 变量只是一个标识符,指向一个对象,而这个对象被创建在内存‘堆’中
- python编程中一般无须关心变量的存亡,一般也不用关心内存的管理
- python使用引用计算来记录所有对象的引用次数;当对象引用次数为0,它就可以被垃圾回收GC
什么是Python GC:
Py的一个大好处,就是灵活的变量声明和动态变量类型。虽然这使得学习py起来非常方便快捷,但是同时也带来了py在性能上的一些不足。其中相关内存比较主要的一点就是py不会对已经销毁的对象所占据的内存做自动的释放内存空间的工作。
为了解决这样的问题,python使用的垃圾回收机制:
Python中,主要依靠gc(garbage collector)模块的引用计数技术来进行垃圾回收。所谓引用计数,就是考虑到Python中变量的本质不是内存中一块存储数据的区域,而是对一块内存数据区域的引用。所以python可以给所有的对象(内存中的区域)维护一个引用计数的属性,在一个引用被创建或复制的时候,让python,把相关对象的引用计数+1;相反当引用被销毁的时候就把相关对象的引用计数-1。当对象的引用计数减到0时,自然就可以认为整个python中不会再有变量引用这个对象,所以就可以把这个对象所占据的内存空间释放出来了。
引用计数技术在每次引用创建和销毁时都要多做一些操作,这可能是一个小缺点,当创建和销毁很频繁的时候难免带来一些效率上的不足。但是其最大的好处就是实时性,其他语言当中,垃圾回收可能只能在一些固定的时间点上进行,比如当内存分配失败的时候进行垃圾回收,而引用计数技术可以动态地进行内存的管理。
计算增加:
赋值给其他变量会增加引用计算
实参传参也会增加引用计算
计算减少:
函数运行结束时,局部变量就会被自动销毁,对象引用计数减少
变量被赋值给其他对象 x=3; y=x; x=4
查看引用计算:
import sys
x=3; y=x; x=4 #引用计算减少
print(sys.getrefcount(x))
在使用函数调用引用计数时会自动加1,使用完函数引用计数会减1
随机数
random模块
- randint(1,5) 随机返回1至5之间的整数
import random
for i in range(6):
print(random.randint(1,5)) ---> 331452
- randrange(1,5) 从指定范围内,按默认指定基数1递增的集合中获取一个随机数
for i in range(6):
print(random.randrange(1,7,2)) ---> 533111
#在使用randrange时,给定的范围值是前包后不包的;
#此时指定的随机取值范围是1至6,基数为2
- choice(seq) 从一个非空序列的元素中随机挑选一个元素,例如random.choice(range(5)),从0至4中随机取一个整数
x=[1,2,3,4,5]
for i in range(6):
print(random.choice(x)) ---> 153122
- choices() 从3.6版本才开始提供,指定次数从样本中随机取值,可重复选择,可指定权重
for i in range(3):
print(random.choices([1,3],[5,1],k=4))
#从1和3两个数中随机取值,权重为1对应5,3对应1,每次取4个数,结果为
[1, 1, 1, 1] [1, 1, 1, 1] [1, 1, 1, 3]
- random.shuffle(list) None就地打乱该列表元素
x=[1,2,3,4,5]
random.shuffle(x)
x ---> [5, 3, 4, 1, 2]
- sample() 从样本空间或总体(序列或者集合类型)中随机取出指定个不同的元素,返回一个新的列表
x=[1,2,3,4,5]
for i in range(6):
print(random.sample(x,k=4))
#每一次从列表x中随机取4个值,每一次取的值都不同
#每一次不会重复挑选同一个值,k的值不能大于样本数,否则报错
#注意是在列表x的不同索引index位置上随机取数,结果为
[5, 4, 3, 2] [1, 5, 3, 4] [2, 1, 5, 4]
sample和choices的区别就在于choices可以在样本的相同索引位置上重复取数,而sample不可以