欢迎观看,欢迎指正,共同学习
1、闭包
目的:延长外部函数的变量的生命周期
构成条件:
1、有嵌套:外部函数里套一个内部函数
2、有引用:内部函数里引用了外部函数的变量
3、有返回:外部函数返回了内部函数名(本质是返回了地址)
格式:
def 外部函数名(a):
def 内部函数名():
引用外部函数变量a
(根据需求return)
return 内部函数名
注意:函数名本质记录的地址
函数引用传递
isinstance():用于判断一个对象是否是一个已知的类型
global: 声明全局变量
nonlocal: 用于声明要修改的是外层函数的局部变量
1.1、闭包入门
def outer():
a = 10
def inner():
nonlocal a
a = 20
print(f'修改的结果:{a}')
return inner
f = outer()
f()
2、装饰器
作用:在不改变原有函数定义和调用的基础上,给原有函数添加额外功能
构成条件:
1、有嵌套
2、有引用
3、有返回
4、有额外功能
写法:
方式1:原生调用语法
变量名 = 装饰器名(原有函数名)
变量名()
方式2:语法糖语法:快捷方式(类似三目运算符,列表推导式)
@装饰器名
注意:同时使用两种方式,会调用两次内部函数
可变参数:
*args:*把所有的位置传参进来的参数放到args元组中
**kwargs:**把所有的关键字传参的参数放到了kwargs字典中
注意:*和**还可以在传参的时候把列表和字典进行自动拆包的操作
*把列表中元素一个个取出,**把字典中的键值对一个个取出作为参数传递
2.1、装饰器原生调用方式
def comment():
print('----发表评论功能开始-----')
print('此处省略很多代码')
print('---发表评论功能结束---')
def outer(func):
"""
定义一个装饰器函数,用于扩展其他函数的功能。
:param func: 被装饰的函数。
:return: 返回一个闭包函数,用于在执行被装饰函数前添加额外功能。
"""
def inner():
"""
闭包函数,用于在被装饰函数执行前添加额外的逻辑。
"""
print('新增验证用户是否登录的功能')
func()
return inner
comment = outer(comment)
comment()
2.2、装饰器语法糖方式
def outer(func):
def inner():
print('新增验证用户是否登录的功能')
func()
return inner
@outer
def comment():
print('----发表评论功能开始-----')
print('此处省略很多代码')
print('---发表评论功能结束---')
comment()
2.3、装饰器装饰可变参数的函数
def outer(func):
def inner(*args,**kwargs):
he = func(*args,**kwargs)
return he
return inner
def get_num(*args,**kwargs):
print(args)
print(kwargs)
sum = 0
for i in args:
sum += i
for i in kwargs.values():
sum += i
return sum
he = get_num(1,2,3,a=4,b=5)
print(he)
2.4、多个装饰器装饰一个函数
def check_user_info(func):
def inner():
print('新增校验用户名好饿密码的功能')
func()
return inner
def check_code(func):
def inner():
print('新增校验验证码的功能')
func()
return inner
@check_code
@check_user_info
def comment():
print('原有发表评论功能...')
comment()
2.5、带参数的装饰器
2.5.1、传统方式
def outer(func,flag):
def inner(a,b):
if flag == "+":
print('正在做加法运算中...')
elif flag == "-":
print('正在做减法运算中.....')
func(a,b)
return inner
def get_sum(a,b):
sum = a + b
print(sum)
def get_diff(a,b):
diff = a - b
print(diff)
if __name__ == '__main__':
get_sum = outer(get_sum,"+")
get_diff = outer(get_diff,"+")
get_sum(2,1)
print('-------')
get_diff(2,1)
2.5.2、语法糖方式
def parameter(flag):
def outer(func):
def inner(a,b):
if flag == "+":
print('正在做加法运算中...')
elif flag == "-":
print('正在做减法运算中.....')
func(a,b)
return inner
return outer
@parameter("+")
def get_sum(a,b):
sum = a + b
print(sum)
@parameter("-")
def get_diff(a,b):
diff = a - b
print(diff)
if __name__ == '__main__':
get_sum(2,1)
print('-------')
get_diff(2,1)
3、深浅拷贝
不可变类型:都没有开辟新空间,都只是引用地址传递
可变类型:直接赋值字面量就是开辟了新的空间,但是变量传递的还是引用地址
拷贝:
拷贝成功:开辟了新的空间 --(拷贝后内容没有影响)
浅拷贝
定义:
创建新对象,其内容是原对象的引用
浅拷贝仅仅只拷贝了一层,拷贝了最外围的对象本身
深拷贝
定义:
拷贝对象及其所包含的所有子对象的独立副本。新对象与原对象完全独立,修改新对象不会影响原对象。
不可变类型深拷贝:不可变类型进行深拷贝不会给拷贝的对象开辟新的内存空间,而只是拷贝了这个对象的引用
深浅拷贝的相同点:
对于不可变类型:都没有开辟新的空间,都只是引用地址传递
对于可变类型只有1层时:都开辟了新的空间,都能拷贝成功
不同点:
对于第2层及以上,只有深拷贝才能开辟新空间,浅拷贝就变成了引用传递
3.1、仅1层示例:
from copy import copy
from copy import deepcopy
a1 = 10
b1 = copy(a1)
c1 = deepcopy(a1)
print(a1, b1, c1)
print(id(a1), id(b1), id(c1))
print('-----------------------------------------------')
a2 = 3.14
b2 = copy(a2)
c2 = deepcopy(a2)
print(a2, b2, c2)
print(id(a2), id(b2), id(c2))
print('-----------------------------------------------')
a3 = "你好"
b3 = copy(a3)
c3 = deepcopy(a3)
print(a3, b3, c3)
print(id(a3), id(b3), id(c3))
print('-----------------------------------------------')
a4 = (1, 2, 3)
b4 = copy(a4)
c4 = deepcopy(a4)
print(a4, b4, c4)
print(id(a4), id(b4), id(c4))
print('============================================================')
a5 = [1, 2, 3]
b5 = copy(a5)
c5 = deepcopy(a5)
print(a5, b5, c5)
print(id(a5), id(b5), id(c5))
print('-----------------------------------------------')
a6 = {1, 2, 3}
b6 = copy(a6)
c6 = deepcopy(a6)
print(a6, b6, c6)
print(id(a6), id(b6), id(c6))
print('-----------------------------------------------')
a7 = {1: 'a', 2: 'a', 3: 'a'}
b7 = copy(a7)
c7 = deepcopy(a7)
print(a7, b7, c7)
print(id(a7), id(b7), id(c7))
3.2、两层即以上嵌套示例:
from copy import copy
from copy import deepcopy
a = [10, 20, [30, 40, ['张三', '王五']]]
b = copy(a)
c = deepcopy(a)
print(a, b, c)
print(id(a), id(b), id(c))
a[0] = 11
print(a, b, c)
print(id(a), id(b), id(c))
print('===================================================================')
print(a[2], b[2], c[2])
print(id(a[2]), id(b[2]), id(c[2]))
a[2][0] = 33
print(a[2], b[2], c[2])
print(id(a[2]), id(b[2]), id(c[2]))
print('------------------------------------------')
print(a[2][2], b[2][2], c[2][2])
print(id(a[2][2]), id(b[2][2]), id(c[2][2]))
a[2][2][0] = '李四'
print(a[2][2], b[2][2], c[2][2])
print(id(a[2][2]), id(b[2][2]), id(c[2][2]))