闭包
# def outer(): # a = 10 # print(f"a is {a}") # outer() # print(a) def outer(x): a = 300 def inner(): print(x+a) return inner #inner()是返回函数值 d = outer(10) d() #引用的外部函数的变量都存在__closure__里面,是个元组类型 #闭包形成的条件: # 1,必须要有一个内嵌函数 # 2,内函数必须引用外函数的变量 # 3,外函数必须返回内函数 # 变量解析原则LEGB: # 先找local # 再找上一层 # 再找global全局 # 再找builtin内建 # def outer(): # tmp_list = [] # def inner(name): # tmp_list.append(1) # print(f"{name} --{tmp_list}") # return inner # d1 = outer() # d2 =outer() # d1("d1") # d2("d2") # print(id(outer()),id(outer()))#内存空间的地址一样:没将他们赋给一个变量,就是匿名变量,匿名变量都会放在同一个空间 #虽然代码一样,但是每次调用外函数,都会重新执行,创建一个新的tmp_list和inne
装饰器是一种设计模式,如果有一个类或者函数希望添加其他或函数的一些功能, # 而不希望通过继承或者直接修改源代码实现 # # 在不改变函数或者类的源代码的基础上,为函数或类添加额外功能 #装饰器的本质就是闭包函数,不同之处是外函数需要传入一个callable对象# import time # def func1(): # time.sleep(2) # print("func1......") # # # def func2(): # time.sleep(3) # print("func2......") # start = time.time() # func1() # end = time.time() # result = end - start # print(result) #统计运行时间的装饰器 # import time # import functools # # 必须传入一个callable对象 # def runtime(func): # #保留传进来的函数的元数据,将他的元数据赋值给inner # @functools.wraps(func) # def inner(*args,**kwargs): #让装饰器更通用 # start = time.time() # result=func(*args) # end = time.time() # print(f"函数执行花了{end-start}s") # return result # return inner # # @runtime #@修饰符去使用装饰器,func1=runtime(func1) # def func1(): # time.sleep(2) # print("func1...") # # @runtime # def func2(a,b): # time.sleep(3) # print("func2...") # return a+b # # func1() # func2(1,2) #要求都写在内函数里面 def deco(username): def login_required(func): def inner(*args): if username == 'root': result = func(*args) return result else: print("no permission") return inner return login_required #add=runtime(login_required(add)) @deco(username = input("input your name")) def compute(a,b): return a+b res=compute(1,2) print(res) #可以应用多个内函数,从最上面的装饰器的内函数开始执行, # 一层一层的内函数往里面执行
装饰器的应用
#自身传入不参数的装饰器,使用两层函数定义 #自身传入参数的装饰器,使用三层函数定义 # import functools # import time # def deco(name): # def runtime(func): # @functools.wraps(func) # def inner(*args, **kwargs): # 让装饰器更通用 # start = time.time() # result = func(*args) # end = time.time() # print(f"函数执行花了{end - start}s") # return result # return inner # return runtime # # #runtime = deco(name="sc") # #func1 = runtime(func1) # @deco(name="sc") # def func1(): # time.sleep(3) # print("this is func1") # func1()
###基于类实现装饰器
# class A(): # def __init__(self,func): # self.func = func # def __call__(self):#添加的东西放到call里面 # print("this is call") # self.func() # @A #本质func1=A(func1) # def func1(): # print("i am func1...") # func1() # import time # class Time(): # def __init__(self,func): # self.func = func # def __call__(self,*args,**kwargs): # start = time.time() # res = self.func(*args,**kwargs) # end = time.time() # print(f"函数执行花了{end-start}s") # return res # # @Time # def func1(): # time.sleep(2) # print("func1") # func1() # #func1就是call
####装饰器带参数 # #func1 = runtime(func1) #先执行实例化得到一个对象 # ,通过对象的调用又得到一个callable对象
###装饰类 def outer(cls): def inner(*args,**kwargs): print(f"class name is:{cls.__name__}") return cls(*args,**kwargs) return inner @outer#本质上就是A= outer(A) class A(): def __init__(self,name): self.name = name print(type(A)) m = A("sc") print(m.name)