目录
global与nonlocal
global # 提升全局变量关键字,在函数内使用
name = '123'
def func()
name = '1111'
func()
print(name) # 123
可变数据类型可以在函数内直接修改不要提升全局变量关键字就可以使用
a = [1,2,3]
def func()
a.append(4)
func()
print(a) [1,2,3,4]
# 在不重新修改命名空间变量赋值的情况下,更改数据值
name = '123'
def func():
global name
name = 'zhang'
func()
print(name) # zhang
nonlocal # 嵌套函数内使用外部函数变量,在函数嵌套内使用
def outer():
name = '123'
def index():
name = '111'
print(name) # '123'
def outer():
name = '123'
def index():
nonlocal name
name = '111'
print(name) # '111'
函数名的多种用法
1.当作数据值
def func():
print(123)
func2 = func
print(fun2) # <function func2 at 0x000001D4D4069A60>
2.当作参数传递
def func1():
print(1)
def func2(v1):
print(v1)
func2(func1) # <function func1 at 0x000002540EDF9A60>
3.当作返回值
def func1():
print(1)
def func2():
print(123)
return func1
res = func2()
print(res) # 123 <function func1 at 0x0000013B51BE9A60>
4.当做容器的数据值
def register():
print('注册')
def login():
print('登录')
def withdraw():
print('提现')
def transfer():
print('转账')
def shopping():
print('购物')
d1 = {
'1':register,
'2':login,
'3'withdraw,
'4':transfer,
'5':shopping
}
while True:
choice = input('选着编号')
if choice not in d1;
print('功能不存在')
res = d1.get('choie')
res()
闭包函数
闭包的定义:
1.在函数内定义函数
2.使用外部变量名
例如
def outer():
name = '123'
def inner():
print(name)
# 尽管没有调用,也叫闭包,因为函数在定义的时候就已经确定了名字查找顺序了
闭包的应用场景:
是另外一种给函数传参的方式
给函数传值的方式一:
直接传递参数
def func(a):
print(a)
func(123)
给函数另一种方式二:
闭包传值
def func():
name = '123'
pwd = '456'
def func2():
print(name,pwd)
func2()
func() # 123 456 # 写死了不好
# 可以这样
def func(name,pwd):
def inner()
print(name,pwd)
func(zhang,123) # zhang 123
name = '123'
def func1():
print(name)
def func2():
name = 111
func1()
func2() # 123 函数调用使用变量名,跟在哪调用没关系,而是跟函数定义时的位置有关系
装饰器简介
1.概念
在不改变原有功能和调用方式的前提下实现新增功能
2.本质
装饰器并不是一们新的技术,而是由函数,参数,返回值,变量名,命名空间,函数名多种用法,闭包组合到一起的结果
3.口诀
对修改封闭 对扩展开放
4.超前知识time模块
time模块
如何导入模块
1.import 模块名
2.from 模块名 import 类\函数
time模块的使用
import time
time.time() # 获取当前时间距1970 1 1 0:0 的时间为浮点型 1665475010.6782117
time.sleep(0.5) # 运行到这一行暂停0.5秒
装饰器推导
import time
def func():
time.sleep(0.5)
print('func')
start_time = time.time()
func()
end_time = time.time()
print(f'运行函数耗时{end_time-start_time}') # 运行函数耗时0.5023610591888428
# 如果需要在多个地方统计这一个函数就需要多次写了,太麻烦了
# 我直接科技很活 我闭包在套一层,先试一下
def func():
time.sleep(0.5)
print('func')
def func2():
start_time = time.time()
func()
end_time = time.time()
print(f'运行函数耗时{end_time-start_time}')
func2()
func2()
# 哦可以了方便了
# 现在我又新的需求了,有好多个函数需要及时,这个时候怎么办,
# 我直接写多个函数,用来了用,感觉还是太麻烦了,诶,我想到了,可以直接把,需要统计的函数名,我直接传递给这个让他来,这样就不要写多个了,方便哈哈哈哈。试一下
def func1():
time.sleep(0.5)
print('func1')
def func2():
time.sleep(0.5)
print('func2')
def outer(funcs):
start_time = time.time()
funcs()
end_time = time.time()
print(f'运行函数耗时{end_time-start_time}')
outer(func1)
'''
func1
运行函数耗时0.5023987293243408
'''
outer(func2)
'''
func2
运行函数耗时0.514385461807251
'''
# 这样是可以了但是改变调用了啊
# 嗯对,我在改改,那我再套一程把他返回出去
def func1():
time.sleep(0.5)
print('func1')
def func2():
time.sleep(0.5)
print('func2')
def outer(funcs):
def inner():
start_time = time.time()
funcs()
end_time = time.time()
print(f'运行函数耗时{end_time-start_time}')
return inner # 返回的是inner 的内存地址
func1 = outer(func1) # 这样就修改了变量名的绑定了,看起来就跟原来一样了,狸猫换太子
func1() # 其实是调用inner的内存地址存放的代码
'''
func1
运行函数耗时0.5052452087402344
'''
func2 = outer(func2)
func2()
'''
func2
运行函数耗时0.5050647258758545
'''
# 嗯very good 很好 但是我现在我给你个函数需要一个参数,你在这样还可以吗?
# 我逝一下
'''
def func1(a):
time.sleep(0.5)
print('func1')
def func2():
time.sleep(0.5)
print('func2')
def outer(funcs):
def inner():
start_time = time.time()
funcs()
end_time = time.time()
print(f'运行函数耗时{end_time-start_time}')
return inner # 返回的是inner 的内存地址
func1 = outer(func1) # 这样就修改了变量名的绑定了,看起来就跟原来一样了
func1() # 其实是调用inner的内存地址存放的代码
TypeError: func1() missing 1 required positional argument: 'a'
'''
#啊寄,报错了,我看看什么错,哦原来是需要一个参数,让我see 一 see 怎么解决,
# 既然你需要,那我就直接给你
'''
def func1(a):
time.sleep(0.5)
print('func1')
def outer(funcs):
def inner(a): # 我给你
start_time = time.time()
funcs()
end_time = time.time()
print(f'运行函数耗时{end_time-start_time}')
return inner
func1 = outer(func1) # 这样就修改了变量名的绑定了,看起来就跟原来一样了
func1(1) # 其实是调用inner的内存地址存放的代码
TypeError: inner() missing 1 required positional argument: 'a'
'''
# 欸还是寄,怎么回事,哦没给原来的传啊,好的我加上
def func1(a):
time.sleep(0.5)
print('func1',a)
def func2(aa,bb):
time.sleep(0.5)
print('func2',aa,bb)
def outer(funcs):
def inner(a):
start_time = time.time()
funcs(a) #这里我加上
end_time = time.time()
print(f'运行函数耗时{end_time-start_time}')
return inner
func1 = outer(func1) # 这样就修改了变量名的绑定了,看起来就跟原来一样了
func1(1) # 其实是调用inner的内存地址存放的代码
'''
func1 1
运行函数耗时0.5107102394104004
'''
func2 = outer(func2) # 这样就修改了变量名的绑定了,看起来就跟原来一样了
func2(1,2) # 其实是调用inner的内存地址存放的代码
'''
TypeError: inner() takes 1 positional argument but 2 were given
'''
#很好,成功啦,但没完全成功
#我再想想,想到了,可以用上次说到的,可变长形参呀,还有可变长实参。这样就可以了呀,好的,开始写代码
def func1(a):
time.sleep(0.5)
print('func1',a)
def func2(aa,bb):
time.sleep(0.5)
print('func2',aa,bb)
def outer(funcs):
def inner(*args,**kwargs):
start_time = time.time()
funcs(*args,**kwargs) #这里我加上
end_time = time.time()
print(f'运行函数耗时{end_time-start_time}')
return inner
func1 = outer(func1) # 这样就修改了变量名的绑定了,看起来就跟原来一样了
func1(1) # 其实是调用inner的内存地址存放的代码
'''
func1 1
运行函数耗时0.5107102394104004
'''
func2 = outer(func2) # 这样就修改了变量名的绑定了,看起来就跟原来一样了
func2(1,2) # 其实是调用inner的内存地址存放的代码
'''
func2 1 2
运行函数耗时0.5015923976898193
'''
# 嘿嘿嘿,成功啦,成功啦,完全成功了
# 别高兴太早了,我还有需求呢,我有个函数有返回值,你看你的还能用吗?
def func1(a):
time.sleep(0.5)
print('func1',a)
def func2(aa,bb):
time.sleep(0.5)
print('func2',aa,bb)
def func3(ab,ac):
print('func3',ab,ac)
return ab
def outer(funcs):
def inner(*args,**kwargs):
start_time = time.time()
funcs(*args,**kwargs) # 这里我加上
end_time = time.time()
print(f'运行函数耗时{end_time - start_time}')
return inner
func1 = outer(func1) # 这样就修改了变量名的绑定了,看起来就跟原来一样了,
func1(1) # 其实是调用inner的内存地址存放的代码
'''
func1 1
运行函数耗时0.5107102394104004
'''
func2 = outer(func2) # 这样就修改了变量名的绑定了,看起来就跟原来一样了
func2(1,2) # 其实是调用inner的内存地址存放的代码
'''
func2 1 2
运行函数耗时0.5015923976898193
'''
func3 = outer(func3)
res = func3('a','b') # 接收返回值啊
'''
None
'''
print(res)
# 额,好像不太行啊,我see see 该怎么做
# 那我可以直接接收真实函数的返回值,然后我再通过狸猫换太子的方式,我给再给他,返回出去啊,ok,想到了就要搞,开搞
def func1(a):
time.sleep(0.5)
print('func1',a)
def func2(aa,bb):
time.sleep(0.5)
print('func2',aa,bb)
def func3(ab,ac):
print('func3',ab,ac)
return ab
def outer(funcs):
def inner(*args,**kwargs):
start_time = time.time()
res = funcs(*args,**kwargs) # 这里我加上
end_time = time.time()
print(f'运行函数耗时{end_time - start_time}')
return res
return inner
func1 = outer(func1) # 这样就修改了变量名的绑定了,看起来就跟原来一样了,
func1(1) # 其实是调用inner的内存地址存放的代码
'''
func1 1
运行函数耗时0.5107102394104004
'''
func2 = outer(func2) # 这样就修改了变量名的绑定了,看起来就跟原来一样了
func2(1,2) # 其实是调用inner的内存地址存放的代码
'''
func2 1 2
运行函数耗时0.5015923976898193
'''
func3 = outer(func3)
'''
运行函数耗时0.0
a
'''
# ok完成了。
# 结束但是还可以优化,下次再讲吧
装饰器模板
def outer(func):
def inner(*args,**kwargs):
res = func(*args,**kwargs)
return res
return inner
res = outer(func)
装饰器语法糖
def outer(func):
def inner(*args,**kwargs):
name = input('用户名')
if name == 'zhang':
res = func(*args,**kwargs)
return res
else:
print('姓名不对')
return inner
@outer # 语法糖
def func1(v1):
print('func1',v1)