目录
一、闭包
1.简单演示
条件
在函数嵌套(函数里面在定义函数)的前提下
内部函数使用了外部函数的变量(还包括外部函数的参数)
外部函数返回了内部函数
def outer():
n = 1
#内部定义
def inner():
#使用外部变量
print(n)
#返回内部函数
return inner
ret = outer()
print(ret)
def Person(name):
def say(msg):
print(name+"Say: "+msg)
return say
tom = Person('tom')
jack = Person('jack')
tom('你好')
jack('早上好')
2.内函数修改外函数变量问题
真常来说内部函数只有对外部函数访问的权利
def outer():
n = 1
def inner():
n += 10
print(n)
print(n)
return inner
func = outer()
func()
需要修饰符
def outer():
n = 1
def inner():
nonlocal n
n += 10
print(n)
print(n)
return inner
func = outer()
func()
需要用nolocal
二、装饰器
1.基础使用
特点:
不修改已有函数的源代码
不修改已有函数的调用方法
给已有函数增加额外的功能
他的本质就是一个闭包函数
我们编辑一个计算函数用时功能的程序
import time
def for1():
for i in range(10000000):
i +=1
print(i)
def start(func):
def inner():
s = time.time()
func()
e = time.time()
print("用时: ",e-s)
return inner
func = start(for1)
func()
用装饰器来写
import time
def start(func):
def inner():
s = time.time()
func()
e = time.time()
print("用时: ",e-s)
return inner
@start
def for1():
for i in range(10000000):
i +=1
print(i)
for1()
由此可见装饰器就是一种语法糖
注意:装饰器这里一定要有参数
2.通用装饰器
参数问题
import time
def start(func):
def inner():
s = time.time()
func()
e = time.time()
print("用时: ",e-s)
return inner
@start
def for1(a):
for i in range(a):
i +=1
print(i)
for1(10000000000000000)
总结一下可能有的四种状态
#无参数,无返回值
def outer1(func):
def inner():
print("装饰1.。。")
func()
print("装饰2.。。")
return inner
@outer1
def show1():
print("show1....")
show1()
print("________________________")
# 有参数,无返回值
def outer2(func):
def inner(msg):
print("装饰1.。。")
func(msg)
print("装饰2.。。")
return inner
@outer2
def show2(msg):
print("show2....",msg)
show2("python")
print("________________________")
# 无参数,有返回值
def outer3(func):
def inner():
print("装饰1.。。")
ret = func()
print("装饰2.。。")
return ret
return inner
@outer3
def show3():
return "shoe3....."
print(show3()+"Nihao")
print("________________________")
# 有参数,有返回值
def outer4(func):
def inner(msg):
print("装饰1.。。")
ret = func(msg)
print("装饰2.。。")
return ret
return inner
@outer4
def show4(msg):
return "shoe3....." +msg
print(show4("python4 ")+"Nihao")
我们需要一个通用的修饰器
def outer(func):
def inner(*args,**kwargs):
print("装饰1.。。")
ret = func(*args,**kwargs)
print("装饰2.。。")
return ret
return inner
#无参数,无返回值
@outer
def show1():
print("show1....")
show1()
print("________________________")
# 有参数,无返回值
@outer
def show2(msg):
print("show2....",msg)
show2("python")
print("________________________")
# 无参数,有返回值
@outer
def show3():
return "shoe3....."
print(show3()+"Nihao")
print("________________________")
# 有参数,有返回值
@outer
def show4(msg):
return "shoe3....." +msg
print(show4("python4 ")+"Nihao")
3.多个修饰器引用
def wrapper_div(func):
def inner(*args,**kwargs):
return "<div>" + func(*args,**kwargs) + '</div>'
return inner
def wrapper_p(func):
def inner(*args,**kwargs):
return "<p>" + func(*args,**kwargs) + '</p>'
return inner
@wrapper_p
@wrapper_div
def show():
return "show inner "
print(show())
执行流程
4.装饰器传参
需要多层函数嵌套来完成
def set_a(msg):
def set_f(func):
def inner():
print("装饰内容: "+msg)
func()
return inner
return set_f
@set_a("你好")
def show():
print("show....")
show()
三、类装饰器
1.callable()和__call__
def show():
print("show")
#这个函数用来测试参数是否是可以调用对象
print(callable(show))
print(callable(1))
print(callable("aa"))
class P():
#当一个类中实现了__call__函数
#那么这个类的实例对象就变成了可调用对象,也就是说,实例对象后面可以加()
def __call__(self, *args, **kwargs):
print("Call run")
tom = P()
print(callable(tom))
tom()
其实也就是说,类本来是不可调用的对象,但是装饰器需要是可调用对象,所以只需要了解这点我们就可以使用了
2.类装饰器的简单使用
class Wra():
def __init__(self,func):
self.func = func
def __call__(self, *args, **kwargs):
print("装饰")
self.func()
@Wra
def show():
print("show...")
show()
结语
这是最后几篇了,接下来更新Linux云计算方面的博客,大家👍啊!