05 垃圾回收机制,用户交互,基本运算符--就是垃圾才难以消化→_→
一、垃圾回收机制GC(详细版)
想了解垃圾,你得先知道一些别的。。。
1、直接引用
变量值直接与变量名捆绑:name = "egon" # egon的引用计数此时是1
就像我(变量名)直接拿着一根绳子(赋值符号)套在狗狗(变量值)的脖子上。。。忽然发现此处有歧义o(╥﹏╥)o
2、间接引用
变量值先被直接引用,然后被容器类型引用:list_name = ["张三",name] # egon的引用计数此时是2
我直接拿着绳子,绳子上套了圈圈,圈圈里面是狗狗
3、引用计数(详细版):
直接引用计数 + 间接引用计数
4、引用计数与GC
当变量值的引用计数为0时,GC机制会启动,清除引用计数为0的变量值。
注意注意注意:通过引用计数来清除存在两大缺陷!!!
第一种:变量值被关联次数的每次的增加或减少都会引发计数机制,效率太低。
第二种:(⊙o⊙)…让我想想,请大佬看下一点!
5、标记清除
你还得知道的知识part_2:关于变量的储存
在定义变量时,变量名与值的内存的联系存在栈区,变量值存在堆区,如下图,定义l1,l2
当执行l1 = l2时,l1原本对应的值的引用计数为0就是内存的垃圾。如下图
引用计数的第二个缺陷:
就是:容器类型会产生循环引用,导致解释器无法通过引用计数清理内存空间,如下图
因此为了解决容器类型的循环引用,出现了标记-清除机制
标记—清除机制就是为了解决引用计数无法清除的垃圾内存而导致内存泄漏的问题。
6、分代回收
也是为了解决引用计数的效率问题,当历经很多次扫描都没被回收的变量值,解释器会认为该变量值会被经常使用,扫描次数会相应减少。缺陷是:可能导致某些变量值的回收会被延迟。
请允许我吐槽一句:靠!引用计数这位老兄的bug也太多了点。。。。
二、与用户交互
1、输入input
name = input("please input your name:")
python3 接收用户的输入,将输入的数据全部存为字符串类型
python2 接收用户的输入,会指定输入数据的类型,方便了开发者,却坑了用户,不推荐不推荐。。。。
2、格式化输出
2.1 老古董 -- %
1、根据位置传值
name = 'egon' age = 18 # 根据位置传值 print('name is %s,age is %s' % (name,age)) # 执行结果:name is egon, age is 18 # 如果你酱紫写的话。。。。。 print('name is %s,age is %s' % (age,name)) # 执行结果:name is 18, age is egon, # 会闹笑话,哈哈哈哈,而且有很多个变量的话记住位置是很难的。
2、根据字典中的关键字传值
res = 'name is %(name)s, age is %(age)s' %{'name':'egon' , 'age' : 18} print(res)
3、% 可以接收任意类型的传值
print('age is %s' % 18) print('age is %s' % [1,23]) print('age is %s' % {'a':23})
2.2 青年期(建议使用,python2.6出现的) -- str.format()
name = 'egon' age = 19 res = 'name is {},age is {}'.format(name,age) print(res) # 按照索引位置传 res = 'name is {0}{0},age is {1}{1}'.format(name,age) print(res) # 按照关键字传值 res = 'name is {name},age is {age}'.format(name = name,age = age) print(res)
2.3 儿童期 -- f(python3.5以后才有的)
name = 'egon' age = 19 res = f'name is {name}, age is {age}' print(res)
三、基本运算符
1、算术运算符
print(10 + 3) print(10 - 3) print(10 * 3) print(10 / 3) print(10 // 3) # 整除运算 print(10 % 3) # 取余运算
print(10**3) # 10的三次方
2、比较运算符
print(10 == 3) print(10 != 3) # != 不等于 print(10 >= 3) print(10 <= 3) print(10 < 3) print(10 > 3)
3、赋值运算符
a = 1 a += 1 # a = a + 1 print(a) # 还有 -=, *=, /=, //=, %=,**=
4、链式赋值
z = y = x = 10 print(x,y,z) # 相当于 # x = 10 # y =x # z = x
5、交叉赋值
m = 1 n = 2 m,n = n,m # 相当于下面的操作 # z = m # m = n # n = z print(m,n)
6、解压赋值
list1 = [1,2,3,4,5,6] # 每个变量对应一个元素,不能多也不能少 a,b,c,d,e,f = list1 print(a,b,c,d,e,f) # 取前三个值 a,b,c,*_ = list1 # *会将没有对应关系的值存在一个列表中,赋值给紧跟在*后面的变量名_ print(a,b,c) print(_) # 取前后三个值 *_,a,b,c = list1 print(a,b,c) print(_)