垃圾回收机制

1.概念

  • 垃圾回收机制(GC):是Python解释器自带一种机制,专门用来回收不可用的变量值所占用的内存空间

2.原理

  • Python的垃圾回收机制(GC)主要使用引用计数(reference counting) 来跟踪和回收垃圾。在引用计数的基础上,通过"标记-清除" (mark and sweep)解决容器对象可能产生的循环引用问题,通过 "分代回收"(generation collection) 以空间换世界的方法提高垃圾回收效率
  • python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略

3.引用计数

  • 引用计数:变量值被变量名关联的次数
  • 引用计数存在一个致命缺陷:循环引用导致内存泄漏
    • 解决办法:标记清除、分代回收、手动GC
1  name = 'jason'           # 'jason'被关联了一个变量名name,称之为引用计数为1
2 name1 = name # 把name的内存地址给了name1,而name、name1都关联了'jason',所以'jason'的引用计数为2
3 del name1 # 解除'jason'和name1的关联,'jason'身上的引用计数变为1
当数据值身上的引用计数为0的时候 就会被垃圾回收机制当做垃圾回收掉
当数据值身上的引用计数不为0的时候 永远不会被垃圾回收机制回收

4.标记清除

  • 专门用于解决循环引用的问题,将内存中程序产生的所有数据值全部检查一遍,查看是否存在循环引用,存在则打上标记 ,之后一次性清除
  • 标记:遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,其余的均为非存活对象,应该被清除。
  • 清除:清除过程中遍历堆中所有的对象,将没有标记的对象全部清除
  • 标记清除算法时,发现栈区内不再有l1与l2(只剩下堆区内二者的相互引用),于是列表1与列表2都没有被标记为存活,二者会被清理掉,这样就解决了循环引用带来的内存泄漏问题。
1   l1 = [11, 22]
2 l2 = [33, 44]
3 l1.append(l2) # l1 = [11, 22, l2列表] 引用计数为2
4 l2.append(l1) # l2 = [33, 44, l1列表] 引用计数为2
5 del l1 # 解除变量名l1与列表的绑定关系,列表引用计数减一
6 del l2 # 解除变量名l1与列表的绑定关系,列表引用计数减一
当内存占用达到临界值的时候 程序会自动停止 然后扫描程序中所有的数据
并给只产生循环引用的数据打上标记 之后一次性清除

5.分代回收

  • 因为标记清除每隔一段时间就需要将所有的数据排查一遍,资源消耗过大,所以为了减轻资源损耗,开发了分代管理。
  • 分代回收:是一种以空间换时间的操作方式,Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代。
  • 分代回收的核心思想是:在历经多次扫描的情况下,都没有被回收的变量,gc机制就会认为,该变量是常用变量,gc对其扫描的频率会降低,
  • Python将内存分为了3“代”,分别对应三个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。
    • 年轻代(第0代):新创建的对象分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把不会回收的对象移到中年代
    • 中年代(第1代):不会回收的对象移到中年代
    • 老年代(第2代):老年代中的对象是存活时间最久的对象,存活于整个系统的生命周期内。

流程控制的理论

1.流程控制的概念:

  • 本质:事物的执行流程
  • 事物的执行流程:
    • 顺序结构:从上到下依次执行
    • 分支结构:根据条件的不同执行不同的代码
    • 循环结构:根据条件判断是否一直在做某件事

流程控制中的必备知识

1.python中使用代码的缩进来表示代码的从属关系
从属关系:缩进的代码(子代码)是否执行取决于上面没有缩进的
2.并不是索引的代码都可以拥有缩进的代码(子代码)
if关键字
3.如果有多行子代码属于同一个父代码 那么这些子代码需要保证相同的缩进量
4.python中针对缩进量没有具体的要求 但是推荐使用四个空格(windows中tab键)
5.当某一行代码需要编写子代码的时候 那么这一行代码的结尾肯定需要加上冒号
6.相同缩进量的代码彼此之间平起平坐 按照顺序结构依次执行

分支结构

  • 基本使用:需要用关键字if编写分支结构

单if分支结构

  • if条件:条件成立之后执行子代码

    • 条件可以是布尔值,也可以是表达式
    • 判断条件可以是一个,也可以是由逻辑运算符链接的多个
username = input('username>>>:')
if username =='jason':
print('老师好')
#嵌套
if 1:
print('哈哈')
print('hhhh')

if...else分支

  • if条件:条件成立之后执行的子代码
  • else条件:条件不成立执行的子代码
  • 判断条件可以是一个,也可以是由逻辑运算符链接的多个
username = input('username>>>:')
if username =='jason':
print('老师好')
else:
print('www')

if...elif...else分支结构

  • if 条件1:条件1成立之后执行的子代码
  • elif 条件2:条件1不成立 ,条件2成立执行的子代码
  • elif 条件3:条件1和2都不成立,条件3成立执行的子代码
  • else: 上述条件都不成立,执行的子代码
  • 中间的elif可以写多个、上述子代码永远只会走一个
  • elif和else都不能单独使用,必须结合if
score = input('请输入学生成绩')
score = int(score) # 将字符串的整数转换成整型的整数
if score > '90':
print('优秀')
elif score > '80':
print('良好')
elif score > '70':
print('一般')
elif score > '60':
print('及格')
else:
print('挂科重修')

if的嵌套使用(有点难)

age = 28
height = 170
weight =110
is_beautiful = True
is_success = True
username = 'tony'
if username == 'tony':
print('tony发现目标')
if age < 30 and height > 160 and weight < 150 and is_beautiful:
print('大妹子 手机掏出来 让我加微信')
if is_success:
print('吃饭 看电影 天黑了...')
else:
print('去你妹的 流氓')
else:
print('看电影太无聊')
else:
print('癞蛤蟆')

循环结构

  • 本质:想让一些代码反复的执行

    while 条件:

    条件成立之后执行的子代码(循环体代码)

    1.先判断条件是否成立

    2.如果成立则执行循环体代码

    3.循环体代码执行完毕后再次回到条件判断处 判断条件是否成立

    4.如果成立 则继续执行循环体代码

    5.按照上述规律依次执行 直到条件不成立才会结束循环体代码的执行
count = 1
while count < 5:
print('hello world')
count +=1
print('下课了')
break  # 强行结束循环体
while循环体代码一旦执行到break会直接结束循环
continue # 直接跳到条件判断处
while循环体代码一旦执行到continue会结束本次循环 开始下一次循环 while 条件:
循环体代码
else:
循环体代码没有被强制结束的情况下 执行完毕就会执行else子代码

while...break语句
* break:表示终止本层循环,其他层的循环不受干扰
* 语法结构
while 条件:
code1
code2 break
code3
...
* 结束循环体的方式
1.自己写结束条件 利用while后面的条件判断
2.在循环体代码中添加关键字强制结束
while True:
name = input('name>>>:')
pwd = input('pwd>>>:')
if name == 'jason' and pwd == '123':
print('登录成功')
# 强制结束
break # 直接结束break所在的循环体 (结束本层循环)
else:
print('用户名或密码错误')
* 验证一个break只能结束它所在那一层的循环体代码
while True:
print('我是外层的循环')
while True:
print('我是内层的循环')
break
break
while...continue语句
* continue:表示跳过本次循环,接下来继续执行本层循环
* 循环打印1到10(按规矩办事) 但是到了7就跳过
count = 1
while count < 11:
if count == 7:
# 让count自增1
count += 1
# 跳过本次循环 直接开始下一次循环
continue
print(count)
count += 1
* 结束本次循环 直接开始下一次循环(也只影响所在的那一层循环而已)
while True:
print(123)
while True:
print(321)
continue
continue
while...else语句
* 定义:如果while循环没有被break掉,则执行else内部代码
count = 1
while count < 11:
print(count)
if count == 7:
break
count += 1
else:
print('循环体按照提前定义好的条件正常结束 则会执行')

作业

建议(一开始不会的时候)

1.先写注释(思维逻辑和想法)

2.先考虑主题功能 再考虑附加功能

# 1.根据用户输入内容打印其权限
'''
jason --> 超级管理员
tom --> 普通管理员
jack,rain --> 业务主管
其他 --> 普通用户
'''
# 1.获取用户输入的用户名
username = input('请输入您的用户名>>>:')
# 2.判断用户名 打印不同的提示>>>:不同的条件执行不同的代码 那么需要使用分支结构
if username == 'jason':
print('超级管理员')
elif username == 'tom':
print('普通管理员')
# elif username == 'jack' or 'rain' : # 错误写法
# elif username == 'jack' or username =='rain': # 正确写法
elif username in ['jack', 'rain']: # 正确写法
print('业务主管')
else:
print('普通用户')
# 2.编写用户登录程序
# 要求:有用户黑名单 如果用户名在黑名单内 则拒绝登录
# eg:black_user_list = ['jason','kevin','tony']
# 如果用户名是黑名单以外的用户则允许登录(判断用户名和密码>>>:自定义)
# eg: oscar 123 # 提前定义好黑名单用户
black_user_list = ['jason','kevin','tony']
# 1.先获取用户输入的用户名和密码
username = input('请输入您的用户名>>>:')
# 3.先判断用户名是否是黑名单用户
if username in black_user_list:
print('您已经被拉黑了 无法消费')
else:
password = input('请输入您的密码>>>:')
# 2.判断用户名和密码是否正确
if username == 'jason' and password == '123':
print('登录成功 来宾一位')
else:
print('用户名或密码错误')
# 3.编写用户登录程序
# 用户如果登录失败 则只能尝试三次
# 用户如果登录成功 则直接结束程序 # 4.定义一个计数器
count_num = 1
while True:
# 6.先判断当前尝试了几次
if count_num == 4:
print('很抱歉 您已经尝试了三次')
break
# 1.获取用户数据
username = input('username>>>:')
password = input('password>>>:')
# 2.校验数据是否正确
if username == 'jason' and password == '123':
print('登录成功')
break # 结束循环体代码
else:
print('用户名或密码错误')
# 5.每错误依次就让计数器自增1
count_num += 1
# 4.猜年龄的游戏
# 假设用户的真实年龄是18 编写一个猜年龄的游戏 获取用户猜测的年龄
# 基本要求:可以无限制猜测 每次猜错给出提示(猜大了 猜小了) 猜对则结束程序
# 拔高练习:每次猜测只有三次机会 一旦用完则提示用户是否继续尝试 用户通过输入n或者y来表示是否继续尝试 如果是y则继续给用户三次猜测机会 否则结束程序 # 1.先定义用户的真实年龄
real_age = 18
# 6.添加循环结构:
while True:
# 2.获取用户猜测的年龄
guess_age = input('你猜一猜我的年龄 好不好呀>>>:')
# 3.由于一会儿需要比较大小 所以要将用户输入的字符串年龄转成整型的年龄
guess_age = int(guess_age) # 有小bug 暂时不考虑
# 4.判断年龄是否猜测正确
if guess_age > real_age:
print('你这小伙子 真讨厌 人家有那么大吗???')
elif guess_age < real_age:
print('哎呀 你真讨厌 人家也没那么小啦' )
else:
print('你真棒 猜对了 嘿嘿嘿')
# 7.猜对了 直接结束循环
break 拔高:
# 1.先定义用户的真实年龄
real_age = 18
# 7.添加一个计数器:
count_num = 1
# 6.添加循环结构:
while True:
# 10.判断当前尝试的次数
if count_num == 4:
choice = input('您已经尝试了三次 是否继续尝试(n/y)>>>:')
# 11.判断用户输入的选择
if choice == 'y':
# 12.重置计数器
count_num = 1
else:
print('下次再来玩哟')
break
# 2.获取用户猜测的年龄
guess_age = input('你猜一猜我的年龄 好不好呀>>>:')
# 3.由于一会儿需要比较大小 所以要将用户输入的字符串年龄转成整型的年龄
guess_age = int(guess_age) # 有小bug 暂时不考虑
# 4.判断年龄是否猜测正确
if guess_age > real_age:
print('你这小伙子 真讨厌 人家有那么大吗???')
# 猜测错了 计时器加一
count_num += 1
elif guess_age < real_age:
print('哎呀 你真讨厌 人家也没那么小啦' )
# 猜测错了 计时器加一
count_num += 1
else:
print('你真棒 猜对了 嘿嘿嘿')
# 7.猜对了 直接结束循环
break

垃圾回收、python中的流程控制的更多相关文章

  1. Python基础之:Python中的流程控制

    目录 简介 while语句 if 语句 for语句 Break Continue pass 简介 流程控制无非就是if else之类的控制语句,今天我们来看一下Python中的流程控制会有什么不太一样 ...

  2. python中的流程控制

    目录 引言 流程控制的分类 分支结构 单if结构 if与else结构 if与elif与else结构 if分支的嵌套 循环结构 while循环 while + break循环 while + conti ...

  3. Java中的流程控制(三)

    关于Java中的流程控制 关于Java中的流程控制 4.do while语句 do while语句的功能和while语句差不多,只不过它是在执行完第一次循环后才检测条件表达式的值,这意味着包含在大括号 ...

  4. python编程中的流程控制

    内容概要 成员运算 身份运算 流程控制 详细 1.成员运算 定义:判断某个个体在不在某个群体内 关键词:in(在) /// not in(不在) 例: num_list = [1, 2, 3, 4, ...

  5. C中的流程控制

    一. 流程控制 l 顺序结构:默认的流程结构.按照书写顺序执行每一条语句. l 选择结构:对给定的条件进行判断,再根据判断结果来决定执行哪一段代码. l 循环结构:在给定条件成立的情况下,反复执行某一 ...

  6. Python学习(七) 流程控制if语句

    在Python中流程控制if语句采用如下格式: if expression : statement elif expression : statement elif expression : stat ...

  7. 从0开始的Python学习006流程控制

    流程控制语句 Python中有三种控制流程语句: if.for.和while. if语句 使用if语句来校验一个条件,如果条件为真(True),运行if-块,如果为假(False),运行else-块. ...

  8. python全栈 流程控制;while 循环 格式化输出 运算符 及编码

    python全栈开发 1循环 2break和continue的区别 3格式化输出 4运算符 5编码 一.流程控制while循环 while条件: 代码块(循环体) 1.死循环; while True; ...

  9. Python自动化开发 - 流程控制

    一.拾遗主题 1.变量 理解变量在计算机内存中的表示 >>> a = "ABC" Python解释器干了两件事情: 在内存中创建了一个'ABC'的字符串: 在内存 ...

  10. python基础之流程控制、数字和字符串处理

    流程控制 条件判断 if单分支:当一个“条件”成立时执行相应的操作. 语法结构: if 条件: command 流程图: 示例:如果3大于2,那么输出字符串"very good" ...

随机推荐

  1. 一篇文章带你掌握主流数据库框架——MyBatis

    一篇文章带你掌握主流数据库框架--MyBatis MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射. 在之前的文章中我们学习了MYSQL和JDBC,但是这些东西远远不 ...

  2. 【一月一本技术书】-【MySQL是怎样运行的】- 8月

    mysql 基础 mysql分为 客戶端/服务端 客户端向服务端发送一段文本(mysql语句),服务器处理后向客户端进程返回一段文本. 查询请求执行过程 客户端->处理连接->查询缓存-& ...

  3. Java基础(标识符,数据类型,数据转换,变量)

    注释 Java中的注释有3种: 单行注释 // 多行注释 /**/ 文档注释 /***/ 注释不会被执行,是给我们写代码的人看的 书写注释是一个非常好的习惯 标识符 Java所有的组成部分都需要名字, ...

  4. 创建一个 autocomplete 输入系统 - 前端 + 后端

    文章转载自:https://mp.weixin.qq.com/s/uqchdrkhdFsof0ZFtECujg 我们经常在网站搜索输入时,会帮我们提醒自动完成的功能,比如: 图片 当我们在百度上搜索 ...

  5. 在k8s中将nginx.conf文件内容创建为ConfigMap挂载到pod容器中

    将nginx.conf文件内容创建为ConfigMap user nginx; worker_processes auto; error_log /var/log/nginx/error.log er ...

  6. 20. 使用Fluentd发送告警邮件

    告警是预防系统故障的一个重要工具,目前已经有许多成熟的方案通过监控系统运行指标来进行阈值预警.今天简单了解一下如何使用Fluentd实现邮件告警功能. Fluentd的告警是基于日志分析实现的,通过监 ...

  7. centos yum安装docker

    cd /etc/yum.repos.d/ mv CentOS-Base.repo CentOS-Base.repo_bak wget -O /etc/yum.repos.d/CentOS-Base.r ...

  8. centos离线安装nvm

    PS:因为项目需,客户现场不能联网需要不同的node版本来切换,里面已经内置好了node 8.11.2和12.1.0 两个版本,使用nvm可以切换 链接:https://pan.baidu.com/s ...

  9. [题解] Codeforces 1268 D Invertation in Tournament 结论,兰道定理

    题目 本题需要用到的结论: 一.兰道定理 二.如果\(n\geq4\),那么\(n\)个点的强连通竞赛图存在\(n-1\)个点的强连通子图. 证明: 现在有一个n-1个点的竞赛图(不一定强连通,称其为 ...

  10. Go实现优雅关机与平滑重启

    前言 优雅关机就是服务端关机命令发出后不是立即关机,而是等待当前还在处理的请求全部处理完毕后再退出程序,是一种对客户端友好的关机方式.而执行Ctrl+C关闭服务端时,会强制结束进程导致正在访问的请求出 ...