函数3
函数3
1.闭包函数
作用域:
1.全局作用域:内置名称空间、全局名称空间
特点:全局存活,全局有效
2.局部作用域:局部名称空间
特点:临时存活,局部有效
global:用来在局部修改全局的不可变类型的值
x = 100 def login(): global x x = 200 login() print(x)
nonlocal:修改局部作用域中外层函数的不可变类型
def f1(): x = 100 def f2(): nonlocal x x = 200 f2() print(x) f1()
2.闭包函数
1.闭函数:被封闭起来的函数=>定义函数内部的函数,闭函数的特点是只能在函数内用
2.包函数:该函数引用了一个名字,该名字是来自与e这一层的
总结:闭包函数指是定义在函数内部的函数引用了一个来自外层函数的作用域中的名字
闭包函数升级:结合函数对象
def outter(): x = 100 def wrapper(): print(x) return wrapper # 千万不要加括号 f = outter() print(f) def foo(): x = 666 f() foo()
为函数传参有两种解决方案
方案一:直接以参数的形式传入
def wrapper(x): print(x) wrapper(100)
方案二:用闭包函数为其传参
def outter(x): # x = 100 def wrapper(): print(x) return wrapper # 千万不要加括号 f = outter(100) f()
3.装饰器
1.什么是装饰器
装饰器指的是装饰别人的工具,装饰指的则是对修改源码以及调用方式是封闭的
综上装饰器指是我们要创建一个工具,该工具可以在遵循原则1和2的前提下还能为被装饰对象添加新功能
原则1:不修改被装饰对象的源代码
原则2:不修改被装饰对象的调用方式
2.为何要用装饰器
为了给源代码加入新功能
3.如何实现装饰器
被装饰者:
import time def index(): print('from index') time.sleep(3) index()
方案一:改变被装饰者的源代码
import time def index(): start = time.time() print('from index') time.sleep(1) end = time.time() print('run time is %s' %(end - start)) index()
方案二:装饰器的功能需要重复编写,代码冗余
import time def index(): print('from index') time.sleep(1) start = time.time() index() end = time.time() print('run time is %s' %(end - start)) start = time.time() index() end = time.time() print('run time is %s' %(end - start))
方案三:解决方案二的代码冗余问题,但是存在问题-》装饰器的功能写死了,只能装饰index函数
import time def index(): print('from index') time.sleep(1) def wrapper(): start = time.time() index() end = time.time() print('run time is %s' %(end - start)) wrapper()
方案四:装饰器的功能写活
import time def index(): print('from index') time.sleep(1) def home(name): print('welcome %s to home page' % name) time.sleep(0.5) return 123 def outter(func): # func = 最原始那个home的内存地址 def wrapper(*args,**kwargs): start = time.time() res = func(*args,**kwargs) # 最原始那个home的内存地址() end = time.time() print('run time is %s' % (end - start)) return res return wrapper home = outter(home) # home = wrapper的内存地址 index = outter(index) # home = wrapper的内存地址 res = home('egon') print(res)
装饰器加语法糖
import time def outter(func): # func = 最原始那个home的内存地址 def wrapper(*args, **kwargs): start = time.time() res = func(*args, **kwargs) # 最原始那个home的内存地址() end = time.time() print('run time is %s' % (end - start)) return res return wrapper @outter # index = outter(index) def index(): print('from index') time.sleep(1) @outter # home = outter(home) def home(name): print('welcome %s to home page' % name) time.sleep(0.5) return 123 res = home('egon') print(res)
4.叠加多个装饰器
装饰器模板
def deco(func): def wrapper(*args,**kwargs): res = func(*args,**kwargs) return res return wrapper
加多个装饰器
def deco1(func1): # func1 = wrapper2的内存地址 def wrapper1(*args,**kwargs): print('===>wrapper1') res1 = func1(*args,**kwargs) print('=====>end wrapper1') return res1 return wrapper1 def deco2(func2): # func2 = wrapper3的内存地址 def wrapper2(*args,**kwargs): print('===>wrapper2') res2 = func2(*args,**kwargs) print('=====>end wrapper2') return res2 return wrapper2 def deco3(func3): # func3 = 最原始那个index的内存地址 def wrapper3(*args,**kwargs): print('===>wrapper3') res3 = func3(*args,**kwargs) print('=====>end wrapper3') return res3 return wrapper3 # index = wrapper1的内存地址 @deco1 # deco1(wrapper2的内存地址) ---> wrapper1的内存地址 @deco2 # deco2(wrapper3的内存地址) ---> wrapper2的内存地址 @deco3 # deco3(最原始那个index的内存地址) ---> wrapper3的内存地址 def index(): print('=======>index') index()
有多个装饰器时,加载顺序时从下往上,运行顺序时从上往下。

浙公网安备 33010602011771号