1.1 闭包

  1、闭包概念

      1. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包

      2. 一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。

      3. 但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。

   2、闭包特点    

      1. 必须有一个内嵌函数

      2. 内嵌函数必须引用外部函数中的变量

      3. 外部函数的返回值必须是内嵌函数

#闭包函数的实例
def outer( a ):
b = 10
def inner(): # 在内函数中 用到了外函数的临时变量
print(a+b) # 外函数的返回值是内函数的引用
return inner if __name__ == '__main__':
demo = outer(5)
demo() # # 在这里我们调用外函数传入参数5
# 此时外函数两个临时变量 a是5 b是10 ,并创建了内函数,然后把内函数的引用返回存给了demo
# 外函数结束的时候发现内部函数将会用到自己的临时变量,这两个临时变量就不会释放,会绑定给这个内部函数
# 我们调用内部函数,看一看内部函数是不是能使用外部函数的临时变量
# demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数

闭包实例

  3、闭包中内函数修改外函数局部变量 

    1、在基本的python语法当中,一个函数可以随意读取全局数据,但是要修改全局数据的时候有两种方法:
        1) global 声明全局变量
        2) 全局变量是可变类型数据的时候可以修改
    2、在闭包情况下使用下面两种方法修改
        1)在python3中,可以用nonlocal 关键字声明 一个变量, 表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。
        2)在python2中,没有nonlocal这个关键字,我们可以把闭包变量改成可变类型数据进行修改,比如列表。

#修改闭包变量的实例
def outer( a ):
b = 10 # a和b都是闭包变量
c = [a] # 这里对应修改闭包变量的方法2
def inner():
# 方法一: nonlocal关键字声明(python3)
nonlocal b
b+=1 # 方法二: 把闭包变量修改成可变数据类型 比如列表(python2)
c[0] += 1
print(c[0])
print(b)
return inner # 外函数的返回值是内函数的引用 if __name__ == '__main__':
demo = outer(5)
demo() # 6 11

闭包中内函数修改外函数局部变量

1.2 Python里的拷贝

   1、预备知识一——python的变量及其存储

      1. python的一切变量都是对象,变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的只本身

      2. 不管多么复杂的数据结构,浅拷贝都只会copy一层。

      理解:两个人公用一张桌子,只要桌子不变,桌子上的菜发生了变化两个人是共同感受的。

>>> str1 = 'hello'
>>> str2 = str1 #1、让str1和str2变量都存储了‘hello’所在的内存地址
>>> id(str1)
22748280
>>> id(str1)
22748280
>>> #2、当str1的值变成‘new hello’后str1的值被重新赋值成'new hello'的内存地址,而str2的值依旧是‘hello’的内存地址
>>> str1 = 'new hello'
>>> id(str1)
22748320
>>> id(str2)
22748280 #3、不管多么复杂的数据结构,浅拷贝都只会copy一层。
>>> sourceList = [1,2,[3,4]]
>>> newList = sourceList >>> l[2][0]=100 >>> sourceList
[1, 2, [100, 4]]
>>> newList
[1, 2, [100, 4]]

不管多么复杂的数据结构,浅拷贝都只会copy一层

   2、浅copy与deepcopy

      1、浅copy:  不管多么复杂的数据结构,浅拷贝都只会copy一层

      2、deepcopy :  深拷贝会完全复制原变量相关的所有数据,在内存中生成一套完全一样的内容,我们对这两个变量中任意一个修改都不会影响其他变量

import copy
sourceList = [1,2,3,[4,5,6]]
copyList = copy.copy(sourceList)
deepcopyList = copy.deepcopy(sourceList) sourceList[3][0]=100 print(sourceList) # [1, 2, 3, [100, 5, 6]]
print(copyList) # [1, 2, 3, [100, 5, 6]]
print(deepcopyList) # [1, 2, 3, [4, 5, 6]]

浅copy与deepcopy

1.3 Python垃圾回收机制

    垃圾回收机制:https://www.cnblogs.com/TM0831/p/10599716.html

  1、引用计数

    1. 原理

        1)当一个对象的引用被创建或者复制时,对象的引用计数加1;当一个对象的引用被销毁时,对象的引用计数减1.
        2)当对象的引用计数减少为0时,就意味着对象已经再没有被使用了,可以将其内存释放掉。

    2. 优点

        引用计数有一个很大的优点,即实时性,任何内存,一旦没有指向它的引用,就会被立即回收,而其他的垃圾收集技术必须在某种特殊条件下才能进行无效内存的回收。

    3. 缺点

        1)引用计数机制所带来的维护引用计数的额外操作与Python运行中所进行的内存分配和释放,引用赋值的次数是成正比的,
        2)这显然比其它那些垃圾收集技术所带来的额外操作只是与待回收的内存数量有关的效率要低。
        3)同时,因为对象之间相互引用,每个对象的引用都不会为0,所以这些对象所占用的内存始终都不会被释放掉。

  2、标记-清除

    1. 说明  

        1)它分为两个阶段:第一阶段是标记阶段,GC会把所有的活动对象打上标记,第二阶段是把那些没有标记的对象非活动对象进行回收。

        2)对象之间通过引用(指针)连在一起,构成一个有向图

        3)从根对象(root object)出发,沿着有向边遍历对象,可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。

              根对象就是全局变量、调用栈、寄存器。

        注:像是PyIntObject、PyStringObject这些不可变对象是不可能产生循环引用的,因为它们内部不可能持有其它对象的引用。

            

          1. 在上图中,可以从程序变量直接访问块1,并且可以间接访问块2和3,程序无法访问块4和5
          2. 第一步将标记块1,并记住块2和3以供稍后处理。
          3. 第二步将标记块2,第三步将标记块3,但不记得块2,因为它已被标记。
          4. 扫描阶段将忽略块1,2和3,因为它们已被标记,但会回收块4和5。

    2、缺点

        1)标记清除算法作为Python的辅助垃圾收集技术,主要处理的是一些容器对象,比如list、dict、tuple等

             因为对于字符串、数值对象是不可能造成循环引用问题。

        2)清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。

   3、分代回收

      1. 分代回收是建立在标记清除技术基础之上的,是一种以空间换时间的操作方式。

      2. Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代)

      3. 他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。

      4. 新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发

      5. 把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推

      6. 老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。

1.4 上下文管理(with)

  1、什么是with语句

      1. with是一种上下文管理协议,目的在于从流程图中把 try,except 和finally 关键字和资源分配释放相关代码统统去掉,简化try….except….finlally的处理流程。

      2. 所以使用with处理的对象必须有enter()和exit()这两个方法

        1)with通过enter方法初始化(enter方法在语句体执行之前进入运行)

        2)然后在exit中做善后以及处理异常(exit()方法在语句体执行完毕退出后运行)

  2、with语句使用场景

      1. with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源

      2. 比如文件使用后自动关闭、线程中锁的自动获取和释放等。

  3、with处理文件操作的实例

with open('/etc/passwd') as f:
for line in f:
print(line)

# 这段代码的作用:打开一个文件,如果一切正常,把文件对象赋值给f,然后用迭代器遍历文件中每一行,当完成时,关闭文件;

# 而无论在这段代码的任何地方,如果发生异常,此时文件仍会被关闭。

 

09: python基础补充的更多相关文章

  1. 3.python基础补充(集合,collection系列,深浅拷贝)

    一.集合 1.集合(set): 把不同的元素组成一起形成集合,是python基本的数据类型.集合元素(set elements):组成集合的成员 python的set和其他语言类似, 是一个无序不重复 ...

  2. python基础补充

    关于模块导入方式: import  random print random.choice(range(10)) 和 from  random import choice print choice(ra ...

  3. python基础补充内容

    知识内容: 1.三元运算表达式 2.python代码编写规范 3.模块导入与使用 4.python文件名 5.python脚本的"__name__"属性 6.python之禅 一. ...

  4. Python基础补充(二) 多核CPU上python多线程并行的一个假象【转】

    在python上开启多个线程,由于GIL的存在,每个单独线程都会在竞争到GIL后才运行,这样就干预OS内部的进程(线程)调度,结果在多核CPU上: python的多线程实际是串行执行的,并不会同一时间 ...

  5. Python 基础补充(一) 列表、元组、集合、字典的区别和相互转换

    一.列表.元组.集合.字典的区别   列表 元组 集合 字典 英文 list tuple set dict 可否读写 读写 只读 读写 读写 可否重复 是 是 否 是 存储方式 值 值 键(不能重复) ...

  6. 第三篇.6、python基础补充

    ''' 不可变:数字,字符串,元组 可变:列表,字典 原子:数字,字符串 容器:列表,元组,字典 直接访问:数字 顺序:字符串,列表,元组 映射访问:字典 ''' #一一对应 a,b,c,d,e='h ...

  7. 十一. Python基础(11)—补充: 作用域 & 装饰器

    十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...

  8. 万恶之源 - Python基础知识补充

    编码转换 编码回顾: 1. ASCII : 最早的编码. ⾥⾯有英⽂⼤写字⺟, ⼩写字⺟, 数字, ⼀些特殊字符. 没有中⽂, 8个01代码, 8个bit, 1个byte 2. GBK: 中⽂国标码, ...

  9. python进阶08 MySQL基础补充

    python进阶08 MySQL基础补充 本次课程都是基于三张表格的使用 一.子查询 #如何找到‘张三’的成绩 #思路:先找到张三的学号,在拿这个张三的学号到成绩表里面去匹配,得出成绩 #如何用一条查 ...

随机推荐

  1. sklearn学习_01

    # -*- coding: utf-8 -*- """ Created on Fri Sep 29 11:05:52 2017 机器学习之sklearn @author: ...

  2. Alpine Linux

    Alpine Linux Docker镜像基于Alpine Linux操作系统,后者是一个面向安全的轻型Linux发行版.不同于通常Linux发行版,Alpine Linux采用了musl libc和 ...

  3. 在本机搭建vue-cli3项目

    vue-cli3官方网址: https://cli.vuejs.org/zh/ 由于公司开始一个新项目,用到的是vue-cli3搭建的项目,所以自己想搭建一个项目,今天搭建的项目就是一个很简单的项目, ...

  4. 洛谷P4138 挂饰 背包

    正解:背包dp 解题报告: 昂先放链接qwq 感觉还挺妙的,,,真的我觉得我直接做可能是想不到背包的,,,我大概想不出是个背包的QAQ 但是知道是背包之后觉得,哦,好像长得也确实挺背包的吼,而且其实是 ...

  5. 位运算求最值 学习笔记 (待补充QAQ)

    没有什么前言?直接进入正题qwq 俩俩异或 求最值: 建trie树 O(n)枚举每个数找这个数的最值,每次反走就成,还可以剪枝一波(如果在某位已经小于ans显然可以直接return? void Ins ...

  6. Hadoop的那些事儿(转)

    原文:http://www.searchtb.com/tag/mapreduce       在说Hadoop之前,作为一个铁杆粉丝先粉一下Google.Google的伟大之处不仅在于它建立了一个强悍 ...

  7. promise VS future

    Future and Promise are the two separate sides of an asynchronous operation. promise is used by the & ...

  8. go-001-环境部署,IDEA插件

    一.下载安装 https://golang.org/dl/ 下载之后安装即可 官网地址:https://golang.org/ 1.1.mac上安装go 1.安装Homebrew 安装命令: ruby ...

  9. C# 序列化(Serialize)与反序列化(Deserialize)

    序列化是将对象的状态信息转换为可保持或传输的格式的过程(一堆字符),比如转化为二进制.xml.json等的过程. 反序列化就是将在序列化过程中所生成的二进制串.xml.json等转换成数据结构或者对象 ...

  10. [LeetCode] 694. Number of Distinct Islands

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...