内存管理机制,运算符
7.29
今日内容:
1、内存管理机制
垃圾回收机制GC
引用计数
分代回收
标记/清除
小整数池
2、与用户交互
接收用户输入
格式化输出
3、运算符
4、流程控制之if判断
**一 垃圾回收机制GC**
垃圾回收机制(简称GC)是Python解释器自带一种机,专门用来回收不可用的变量值所占用的内存空间
**# 1.1 引用计数**
# 引用计数增加
x = 18 # 值18的引用计数为1
y = x # 值18的引用计数为2
l = [111, x] # 值18的引用计数为3
# print(id(x))
# print(id(y))
# print(id(l[1]))
**# 引用计数减少**
# del x # 值18的引用计数为2
# y = 100 # 值18的引用计数为1
# del l[1] # 值18的应用计数为0
**# 1.2 分代回收**:为了解决引用计数的效率问题
分代指的是根据存活时间来为变量**划分不同等级**(也就是不同的代)
回收依然是使用引用计数作为回收的依据
# 问题:个别垃圾有可能得不到及时的清理
(堆区与栈区
在定义变量时,变量名与变量值都是需要存储的,分别对应内存中的两块区域:堆区与栈区。
# 1、变量名与值内存地址的关联关系存放于栈区
# 2、变量值存放于堆区,内存管理回收的则是堆区的内容
直接引用指的是从栈区出发直接引用到的内存地址。
间接引用指的是从栈区出发引用到堆区后,再通过进一步引用才能到达的内存地址。)
# 1.3 标记/清除:为了解决循环引用带来的内存泄漏问题
循环引用会导致:值不再被任何名字关联,但是值的引用计数并不会为0,应该被回收但不能被回收
# 核心:一个变量值没有任意一条可以从栈区出发到自己的引用,就会被标记下来,方便后续清除
# lll = [66,77,[88,99]]
# l1 = [111]
# l2 = [222]
# l1.append(l2)
# l2.append(l1)
# print(l1) # l1 = [111的内存地址,l2的内存地址]
# print(l2) # l2 = [222的内存地址,l1的内存地址]
# print(l1[1][1])
# del l1
# print(l2[1][0])
# del l2
**二 小整数池**
x = 100000
y = 100000
print(id(x)) = print(id(y)) 同一缓存机制
print(id(x)) != print(id(y)) 不同缓存机制
**同一代码块的缓存机制**
1.id is ==
2.代码块
。代码块:我们所有的代码都需要依赖代码块执行。
。一个文件就是一个代码块。
。交互式命令下一行就是一个代码块。
3两个机制:同一个代码块下,有一个机制。不同的代码块下,遵循另一个机制。
4同一个代码块下的缓存机制。
前提条件:同一个代码块内。
机制内容:pass
适用的对象:int bool str
具体细则:所有的数字, bool,几乎所有的字符串。
优点:提升性能,节省内存。
**不同代码块下的缓存机制**
小数据池:
。前提条件:不同代码块内。
。机制内容:pass
。适用的对象:int bool str
。具体细则:-5~256数字,bool,满足规则的字符串。
。优点:提升性能,节省内存。
**总结:**
1.面试题考。
2回答的时候一定要分清楚:同一个代码块下适用一个缓存机制。不同的代码块下适用另一个缓存机制(小数据池)
3小数据池:数字的范围是-5~256.
4.缓存机制的优点:提升性能,节省内存。
**1、接收用户输入**
python3中的input会把用户输入的所有内容都存成str类型
age = input("请输入您的年龄: ") # "内容"
print(age,type(age))
age=int(age)
print(age > 10) # "18" > 10
补充:int可以把纯数字组成的字符串转换整型
int("31") # ok
res = int(" 31 ") # ok
res = int("3 1") # no
print(res,type(res))
python2(***)
raw_input()与python3的input一模一样
input()要求用户必须输入一个明确的数据类型,输入什么类型就存成什么类型
**2、输出**
print("hello1",end='*')
print("hello2",end='*')
print("hello3",end='*')
格式化输出
msg = "my name is %s my age is %s" % ("egon", "18")
msg = "my name is %s my age is %d" % ("egon", 18)
msg = "my name is %s my age is %s" % ("egon", 18)
msg = "my name is %s my age is %s" % ("egon", [1,2,3])
print(msg)
**格式化输出之format**
之前我们使用%s来做字符串的格式化输出操作,在传值时,必须严格按照位置与%s一一对应,而字符串的内置方法format则提供了一种不依赖位置的传值方式
案例:
# format括号内在传参数时完全可以打乱顺序,但仍然能指名道姓地为指定的参数传值,
name=‘tony’就是传给{name}
>>> str4 = 'my name is {name}, my age is {age}!'.format(age=18,name='tony')
>>> str4
'my name is tony, my age is 18!'
>>> str4 = 'my name is {name}{name}{name}, my age is {name}!'.format(name='tony', age=18)
>>> str4
'my name is tonytonytony, my age is tony!'
**format的其他使用方式(了解)**
# 类似于%s的用法,传入的值会按照位置与{}一一对应
>>> str4 = 'my name is {}, my age is {}!'.format('tony', 18)
>>> str4
my name is tony, my age is 18!
# 把format传入的多个值当作一个列表,然后用{索引}取值
>>> str4 = 'my name is {0}, my age is {1}!'.format('tony', 18)
>>> str4
my name is tony, my age is 18!
>>> str4 = 'my name is {1}, my age is {0}!'.format('tony', 18)
>>> str4
my name is 18, my age is tony!
>>> str4 = 'my name is {1}, my age is {1}!'.format('tony', 18)
>>> str4
my name is 18, my age is 18!
**2.1 算术运算符**
x = 10
y = 20
print(x + y)
print(10 + 20)
print(10 // 3) #整除=3
print(10 / 3)
print(10 % 3) #取余=1
print(10 ** 2)
print(10 + 3.1)
了解:+与*
print("abc"+"def")
print([1,2,3]+[3,4,5])
print("abc"*3)
print([1,2,3]*3)
补充:python是一门解释型、强类型、动态语言
补充:go是一门编译型、强类型、静态语言
"18" + 10
x = 10
**2.2 比较运算符**
判断是否相等,没有类型限制
print("abc" == 10) # 判断的是值及其类型是否相等
print("abc" != 10) # 判断的是值及其类型是否相等
> >= < <=:主要用于数字类型
print(10 > 3.1)
了解:> >= < <=也可以给其他类型用,但仅限于同类型之间
x = "abcdefg"
y = "abz"
print(x > y)
x = [111, 'abcdefg', 666]
y = [111,'z']
print(x > y)
**2.3 赋值运算符**
2.3.1 增量赋值
age = 18
age += 1 # age = age + 1
age -= 1 # age = age - 1
print(age)
**2.3.2 链式赋值**
x = y = z = 100
2.3.3 交叉赋值
x = 100
y = 200
temp = x
x = y
y = temp
del temp
x,y=y,x
print(x) # 200
print(y) # 100
2.3.4 解压赋值
ps:字符串、字典、元组、集合类型都支持解压赋值
salaries = [11, 22, 33, 44, 55]
mon1 = salaries[0]
mon2 = salaries[1]
mon3 = salaries[2]
mon4 = salaries[3]
mon5 = salaries[4]
mon1, mon2, mon3, mon4, mon5 = salaries
print(mon1, mon2, mon3, mon4, mon5)
mon1,mon2,*_ ,last = salaries
print(mon1)
print(mon2)
print(_)
_,*x,_ = salaries
print(x)
了解:
x, y, z = {'k1': 111, 'k2': 222, 'k3': 3333}
x, y, z = "abc"
print(x,y,z)
**2.4 逻辑运算符**
逻辑运算符是用来运算条件的,那什么是条件???
只要结果为布尔值的都可以当做条件
**总结:逻辑运算符,算的是显式的布尔值或者隐式的布尔值**
2.4.1 not
print(not 10 > 3)
print(not False)
print(not 123)
2.4.2 and: 链接多个条件,多个条件必须同时成立,最终结果才为True
print(10 > 3 and True and 'xx' == 'xx')
print(10 > 3 and False and 'xx' == 'xx')
print(10 > 3 and None and 'xx' == 'xx')
print(10 > 3 and True and 'xx' == 'xx' and 111)
2.4.3 or: 链接多个条件,多个条件但凡有一个成立,最终结果就为True
print(10 > 3 or False or 'xx' == 'xx')
print(0 or None or "" or 1 or True or 10 > 3)
强调:优先级not>and>or
print(3 > 4 and 4 > 3 or 1 == 3 and not 'x' == 'x' or 3 > 3)
(3 > 4 and 4 > 3) or (1 == 3 and not 'x' == 'x') or 3 > 3
**2.5 成员运算符**
print("abc" in "xxxabcxxxxx")
print(111 in [222,333,1111])
print('k1' in {'k1':111,'k2':222}) # 字典的成员运算判断的是key
print('k3' not in {'k1': 111, 'k2': 222}) # 推荐
print(not 'k3' in {'k1': 111, 'k2': 222}) # 不推荐
**2.6 身份运算符**:is判断的是id是否一样
x = 100
y = x
print(x is y)
print(x == y)
**总结:==成立is不一定成立,但是is成立==一定成立**
#1. id相同,内存地址必定相同,意味着type和value必定相同
#2. value相同type肯定相同,但id可能不同
x与z的id不同,但是二者的值相同
x = y = [4,5,6]
z = [4,5,6]
print(x==y) #True
print(x==z) #True
print(x is y) #True
print(x is z) #False
print(id(x)) #1267621360128
print(id(y)) #1267621360128
print(id(z)) #1267621189632
**注:id内容不固定,每次运行都会改变**
>>> a = 1 #a和b为数值类型
>>> b = 1
>>> a is b
True
>>> id(a)
14318944
>>> id(b)
14318944
>>> a = 'cheesezh' #a和b为字符串类型
>>> b = 'cheesezh'
>>> a is b
True
>>> id(a)
42111872
>>> id(b)
42111872
>>> a = (1,2,3) #a和b为元组类型
>>> b = (1,2,3)
>>> a is b
False
>>> id(a)
15001280
>>> id(b)
14790408
>>> a = [1,2,3] #a和b为list类型
>>> b = [1,2,3]
>>> a is b
False
>>> id(a)
42091624
>>> id(b)
42082016
>>> a = {'cheese':1,'zh':2} #a和b为dict类型
>>> b = {'cheese':1,'zh':2}
>>> a is b
False
>>> id(a)
42101616
>>> id(b)
42098736
>>> a = set([1,2,3])#a和b为set类型
>>> b = set([1,2,3])
>>> a is b
False
>>> id(a)
14819976
>>> id(b)
14822256
**注:**只有数值型和字符串型的情况下,a is b才为True,当a和b是tuple,list,dict或set型时,a is b为False(只数字在-5到256之间它们的id才会相等,超过了这个范围就不行了,同样的道理,字符串对象也有一个类似的缓冲池,超过区间范围内自然不会相等了)

浙公网安备 33010602011771号