闭包函数
1.闭:定义在函数内部的函数
2.包:内部函数引用了外部函数作用域的名字
# def outter(): # x = 111 # def inner(): # print(x) # return inner # res = outter() # res就是inner函数内存地址 # # def func(): # x = 333 # res() # func() # 给函数体传值的第一种方式 传参 # def index1(username): # print(username) # # # 给函数体传参的第二种方式 闭包 # def outter(x,y): # # x = 1 # # y = 40 # def my_max(): # if x > y: # return x # return y # return my_max # res1 = outter(1,40) # res就是my_max函数的内存地址 # print(res1()) # print(res1()) # print(res1()) # res2 = outter(90,200) # print(res2()) # print(res2()) # print(res2()) # print(res2()) # print(res2()) # print(res2())
2.装饰器
#装饰器: 开放封闭原则:
# 开放:对扩展开放
# 封闭:对修改封闭
#装饰器必须遵循的两个原则:
# 1.不改变被装饰的对象的代码
# 2,不改变被装饰(可调用对象)对象的调用方式
import time #被装饰的对象 def index(): time.sleep(3) print('hello word') def outer(func): #func = index def get_time(func): #func = 最原始的index函数的内存地址 start = time.time() func() #func = index函数的内存地址()直接调用 end = time.time() print('index run time:%s'%(end - start)) return get_time index = outer(index) #outer(最原始的index函数的内存地址) index()
3,装饰器简单版
""" 1.统计index函数执行的时间 """ import time def index(): time.sleep(3) print('澳门最大线上赌场开业啦 性感tank在线发牌!') def outter(func): # func = 最原始的index函数的内存地址 def get_time(): start = time.time() func() # func = index函数的内存地址() 直接调用 end = time.time() print('index run time:%s'%(end-start)) return get_time index = outter(index) # outter(最原始的index函数内存地址) # index指向get_time函数的内存地址 index()
4,装饰器升级版
import time def index(): time.sleep(3) print('澳门最大线上赌场开业啦 性感tank在线发牌!') return 'index' res1 = index() def login(name): time.sleep(1) print('%s is sb'%name) return 'login' res = login('egon') 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 # login = outter(login) # outter(最原始的login函数的内存地址) # res = login('egon') # print(res) # index = outter(index) # res1 = index() # print(res1) """ 函数参数的问题 无参函数和有参函数都可以直接调用??? 函数可以接收任意数量的参数 """
5,装饰器语法糖
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('澳门最大线上赌场开业啦 性感tank在线发牌!') 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('egon') home() """ 语法糖在书写的时候应该与被装饰对象紧紧挨着 两者之间不要有空格 """
6,装饰器模板
def outter(func): def inner(*args,**kwargs): print('执行被装饰函数之前 你可以做的操作') res = func(*args,**kwargs) print('执行被装饰函数之后 你可以做的操作') return res return inner """ 认证装饰器 执行函数index之前必须先输入用户名和密码 正确之后才能执行index 否则提示用户输入错误 结束程序 """ import time user_dic = {'is_login':None} def login_auth(func): # func = index def inner(*args,**kwargs): if user_dic['is_login']: res = func(*args, **kwargs) return res else: 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') return inner # index = login_auth(index) # home = login_auth(home) # index('egon') # home() @login_auth def index(name): time.sleep(1) print('%s is dsb'%name) return 666 @login_auth def home(): time.sleep(1) print('home') return 999 # index('egon') print(index) # home() print(home)
7,多层装饰器
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()