闭包
闭包的作用
闭包可以保存函数内的变量,而不会随着调用完函数而被销毁。
定义一个函数用于保存变量10,然后调用函数返回值变量并重复累加数值,观察效果。

闭包的语法
内部函数使用了外部函数的变量,并且外部函数返回了内部函数,
这种: 使用外部函数变量的内部函数称为闭包。


闭包的构成条件
- 有嵌套: 在函数嵌套(函数里面再定义函数)的前提下;
- 有引用: 内部函数使用了外部函数的变量(还包括外部函数的参数);
- 有返回: 外部函数返回了内部函数名。
nonlocal关键字
global: 声明全局变量
nonlocal: 声明能够让内部函数去修改外部函数的变量
编写一个闭包,让内部函数去访问外部函数内的参数a=100,观察效果。

装饰器
装饰器语法
装饰器的作用是不改变原有函数的基础上,给原有函数增加额外功能。
装饰器本质上就是一个闭包函数。

装饰器语法
案例: 例如发表评论前,都是需要先登录的。
需求: 先定义有发表评论的功能函数,然后在不改变原有函数的基础上,需要提示用户要先登录。




装饰器的使用
装饰器装饰无参无返回值的函数

装饰器装饰有参无返回值的函数

装饰器装饰无参有返回值的函数

装饰器装饰有参有返回值的函数

通用装饰器的使用(函数参数是不定长的,有返回值)

小结
装饰器的内部函数格式要和 被装饰的原函数保持一致,
原函数是无参无返回的,则 装饰器的内部函数也必须是无参无返回的.
原函数有参有返回的,则 装饰器的内部函数也必须是 有参有返回的.
多个装饰器的使用
多个装饰器装饰一个函数
- 例如,发表评论前,都是需要先登录用户再进行验证码验证。
- 先定义有发表评论的功能函数,然后在不改变原有函数的基础上,需要先检查用户登录和输入验证码

多个装饰器的装饰过程是: 离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的装饰过程
带有参数的装饰器
定义一个既能装饰减法运算,又能装饰加法运算的装饰器,即带有参数的装饰器。
- 你大概会有这样的思路, 但是这样运行会报错, 因为装饰器只允许有一个参数

正确的思路应该如下, 在装饰器外面包裹一个函数, 使用该函数接收参数,返回装饰器

深浅拷贝
可变类型与不可变类型
不可变对象: 一旦创建就不可修改的对象,包括字符串、元组、数值类型(整型、浮点型)
该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。
可变对象: 可以修改的对象,包括列表、字典、集合
该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟新的地址,通俗点说就是原地改变。
变量赋值执行原理

Python解释器干的事情:
- 创建变量a
- 创建一个对象(分配一块内存),来存储值'python'
- 将变量与对象,通过指针连接起来,从变量到对象的连接称之为引用(变量引用对象)

浅拷贝
创建新对象,其内容是原对象的引用。
- 浅拷贝之所以称为浅拷贝,是它仅仅只拷贝了一层,拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已
- 原始数据

- 可变类型浅拷贝

- 不可变类型浅拷贝

深拷贝
深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。
- 深拷贝出来的对象是一个全新的对象,不再与原来的对象有任何关联。所以改变原有被复制对象不会对已经复制出来的新对象产生影响。
- 可变类型深拷贝

- 不可变类型深拷贝
不可变类型进行深拷贝不会给拷贝的对象开辟新的内存空间,而只是拷贝了这个对象的引用。

总结:
- 所谓的深浅拷贝分别指的是:
- 浅拷贝: copy模块的copy()函数
- 深拷贝:copy模块的deepcopy()函数
- 大白话解释深浅拷贝:
- 深拷贝拷贝的多,浅拷贝拷贝的少.
- 深浅拷贝的区别主要针对于可变类型, 深拷贝会开辟独立空间, 实现值拷贝,浅拷贝就是拷贝地址
- 如果是针对于不可变类型,深浅拷贝都是拷贝地址, 相当于普通赋值一样.