目录
一、闭包
1.简单演示
2.内函数修改外函数变量问题
二、装饰器
1.基础使用
2.通用装饰器
3.多个修饰器引用
4.装饰器传参
三、类装饰器
1.callable()和__call__
2.类装饰器的简单使用
结语
一、闭包
1.简单演示
条件
在函数嵌套(函数里面在定义函数)的前提下
内部函数使用了外部函数的变量(还包括外部函数的参数)
外部函数返回了内部函数
def outer():n = 1#内部定义def inner():#使用外部变量print(n)#返回内部函数 return innerret = outer()
print(ret)
def Person(name):def say(msg):print(name+"Say: "+msg)return saytom = Person('tom')
jack = Person('jack')
tom('你好')
jack('早上好')
2.内函数修改外函数变量问题
真常来说内部函数只有对外部函数访问的权利
def outer():n = 1def inner():n += 10print(n)print(n)return innerfunc = outer()
func()
需要修饰符
def outer():n = 1def inner():nonlocal nn += 10print(n)print(n)return innerfunc = outer()
func()
需要用nolocal
二、装饰器
1.基础使用
特点:
不修改已有函数的源代码
不修改已有函数的调用方法
给已有函数增加额外的功能
他的本质就是一个闭包函数
我们编辑一个计算函数用时功能的程序
import timedef for1():for i in range(10000000):i +=1print(i)def start(func):def inner():s = time.time()func()e = time.time()print("用时: ",e-s)return innerfunc = start(for1)
func()
用装饰器来写
import timedef 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 +=1print(i)for1()
由此可见装饰器就是一种语法糖
注意:装饰器这里一定要有参数
2.通用装饰器
参数问题
import timedef 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 +=1print(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 retreturn inner@outer3
def show3():return "shoe3....."print(show3()+"Nihao")print("________________________")# 有参数,有返回值
def outer4(func):def inner(msg):print("装饰1.。。")ret = func(msg)print("装饰2.。。")return retreturn inner@outer4
def show4(msg):return "shoe3....." +msgprint(show4("python4 ")+"Nihao")
我们需要一个通用的修饰器
def outer(func):def inner(*args,**kwargs):print("装饰1.。。")ret = func(*args,**kwargs)print("装饰2.。。")return retreturn 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....." +msgprint(show4("python4 ")+"Nihao")
3.多个修饰器引用
def wrapper_div(func):def inner(*args,**kwargs):return "<div>" + func(*args,**kwargs) + '</div>'return innerdef 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 innerreturn 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 = funcdef __call__(self, *args, **kwargs):print("装饰")self.func()@Wra
def show():print("show...")
show()
结语
这是最后几篇了,接下来更新Linux云计算方面的博客,大家👍啊!