函数的闭包
闭:定义在函数内部的的函数
包:内部函数用了外部的函数的作用域的名字
例如:一个简单的例子
def outter(): x = 11 def inner(): print(x) return inner res = outter() #把inner的内存地址赋值给res了 def func(): x =333 res() #等价于inner() func() #111
在给函数体传值的时候有两种方式:
1.传参
def outter(name): print(name)
2.闭包
def outter(x,y): def inner(): if x > y: return x return y return inner res = outter(1,4) res()
介绍了一个模块:
import requests
第一个直接给函数传值
url1 = 'https://www.baiducom' def my_get(url1) response =requests.get(url1) if response.status_code == 200: print(len(response.text) my_get(url1)
第二个是闭包的形式传参
def outter(url): def inner(): response = requests.get(url) if response.status_code == 200: print(len(response.text)) return inner res = outter('https://www.baidu.com')
装饰器(*******)
我们可以把器当成一个工具,装饰就是给对象添加一些别的功能
为什么要使用装饰器:
开放封闭的原则:
开放:对扩展开放
封闭:对修改封闭
装饰器要遵循两个原则:
1.不改变装饰对象的源代码
2.不改变被装饰的对象
这只是一个简易的装饰器
升级版的装饰器
import time def index(): time.sleep(3) print('你好') return 'index' def login(): time.sleep(1) print('您好') return 'login' def outter(func): def inner(*args,**kwargs) start = time.time() res = func(*args,**kwargs) return res end = time.time() print('时间是%s'%(end-start) return inner index = outter(index) login = outter(login) index() login()
装饰器语法糖
import time def outter(func): # func = 最原始的index函数的内存地址 def get_time(*args, **kwargs): start = time.time() res = func(*args, **kwargs) # 最原始的login函数的内存地址() 直接调用 func('egon') end = time.time() print('func run time:%s'%(end-start)) return res return get_time # login = outter(login) # outter(最原始的login函数的内存地址) # index = outter(index) # home = outter(home) @outter # index = outter(index) outter(最原始的index的函数的内存地址) def index(): time.sleep(3) print('你好') return 'index' # res1 = index() @outter # login = outter(login) def login(name): time.sleep(1) print('%s is sb'%name) return 'login' # res = login('egon') @outter # home = outter(home) def home(*args,**kwargs): time.sleep(1) return 'home' # login = outter(login) # outter(最原始的login函数的内存地址) # index = outter(index) # home = outter(home) index() login('yzy') home()
语法糖的书写要求:
1.语法糖在书写的时候应该与被装饰对象紧紧挨着
2.两者之间不能有空格
对我们来说有一个比较简便的装饰器模板
def outter(func): def inner(*args,**kwargs): print('执行被装饰函数之前 你可以做的操作') res = func(*args,**kwargs) print('执行被装饰函数之后 你可以做的操作') return res return inner
多层装饰器:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time user_dic = {'is_login':None} def outter(func): # func = 最原始的login函数的内存地址 def get_time(*args, **kwargs): # args = ('egon',) kwargs = {} start = time.time() res = func(*args, **kwargs) # 最原始的login函数的内存地址() 直接调用 func('egon') end = time.time() print('func run time:%s'%(end-start)) return res return get_time def login_auth2(data_source,x,t): # data_source = 'file' def login_auth(func): # func = index def inner(*args,**kwargs): # 这里的参数是跟被装饰函数的参数一一对应 if user_dic['is_login']: res = func(*args, **kwargs) return res else: if data_source == 'file': username = input('please input your username>>>:').strip() password = input('please input your password>>>:').strip() if username == 'jason' and password == '123': user_dic['is_login'] = True res = func(*args,**kwargs) return res else: print('username or password error') elif data_source == 'MySQL': print('from MySQL') elif data_source == 'ldap': print('ldap') else: print('暂无该数据来源') return inner return login_auth # 装饰器在装饰的时候 顺序从下往上 # 装饰器在执行的时候 顺序从上往下 # res = login_auth2('MySQL') @login_auth2('file',1,2) # index = login_auth(get_time) index = inner函数的内存地址 # @login_auth @outter # get_time = outter(index) index是最原始的index def index(): time.sleep(1) print('index') return 'index' index()
装饰器的修复技术
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time user_dic = {'is_login':None} def outter(func): # func = 最原始的login函数的内存地址 def get_time(*args, **kwargs): # args = ('egon',) kwargs = {} start = time.time() res = func(*args, **kwargs) # 最原始的login函数的内存地址() 直接调用 func('egon') end = time.time() print('func run time:%s'%(end-start)) return res return get_time def login_auth2(data_source,x,t): # data_source = 'file' def login_auth(func): # func = index def inner(*args,**kwargs): # 这里的参数是跟被装饰函数的参数一一对应 if user_dic['is_login']: res = func(*args, **kwargs) return res else: if data_source == 'file': username = input('please input your username>>>:').strip() password = input('please input your password>>>:').strip() if username == 'jason' and password == '123': user_dic['is_login'] = True res = func(*args,**kwargs) return res else: print('username or password error') elif data_source == 'MySQL': print('from MySQL') elif data_source == 'ldap': print('ldap') else: print('暂无该数据来源') return inner return login_auth # 装饰器在装饰的时候 顺序从下往上 # 装饰器在执行的时候 顺序从上往下 # res = login_auth2('MySQL') @login_auth2('file',1,2) # index = login_auth(get_time) index = inner函数的内存地址 # @login_auth @outter # get_time = outter(index) index是最原始的index def index(): time.sleep(1) print('index') return 'index' index()