我觉得在开始学一种东西时,应该用20%的时间读取80%的基础内容,剩下20%的内容需要用80%的时间才能深入理解,这篇文章就是让你用20%的时间读取80%的内容的
本文参考https://foofish.net/python-decorator.html
在python这种动态语言里,一切都是对象,包括函数也是对象,所以便有了闭包
由于本人见识浅短,如果错误请各位大佬指正,非常感谢!
什么是闭包
这个函数内含还含有一个函数,并且这个内嵌函数,使用了外部函数的参数
上面这种函数,便被称为闭包。跟普通函数的不同是,内嵌函数p_name用了外部函数的变量name,使外部变量生命周期被延长了。而普通函数的变量,在进入其他函数时,变量便无法再用了
这种内部函数调用外部变量的行为,就叫做闭包。
变量生命周期被延长是因为闭包会使用python中一个魔法属性__closure__,它负责把外部变量生命周期延长。
你可以这样理解以记忆,不管怎样,name的缩进还是放在print_func里的,所以在内部函数p_name里能用理所当然(有些人就是这样理解的,虽然不太对)
闭包有什么用?闭包用处就大了,我们平常用的装饰器,就是闭包实现的
如果,我们不是传入一个字符串作为参数,而是传入函数作为参数呢
输出
, 把函数当成参数传入,目的是为了在此函数运行之前加点什么, 由于传入的函数是set_string,执行顺序为:
执行顺序
print_func不重要,它只是用来传参的,重要的是p_name,它在添加内容
如果你需要使用参数:
输出
一般来说,p_name跟set_string参数个数要保持一致。
装饰器
其实上面传入函数的例子,就是装饰器了,python使用@来使用装饰器, 此时name是一个函数对象,即set_string('Tory')
你可以这么认为:是先执行set_string(string)的头部部分,然后进入print_func, 到执行完p_name里的内容,最后执行set_string(string)缩进部分的内容
如果你需要使用到函数实例里的参数,可以使用*args与**kwargs接受函数所有参数,比如这么写
,输出
如果你需要让装饰器应用更多的场景, 可以用三层嵌套,通过传入参数
输出
name依旧对应着函数对象,由于我们的装饰器里传入参数,所以就以内嵌函数来对应函数对象
装饰函数后方
如果想要装饰函数后方,可以在最里层,在运行函数时,在函数运行后进行代码编写,(最里层可以不写return,因为它是直接用函数指针运行函数, 区别是前面return时不带括号,是函数本体,最里面一个是带括号的,是运行实例)
装饰器有什么用?
具体有什么用呢。可以用来控制执行顺序,一般体现在,给函数加上什么说明或者日期。。如果你知道什么是框架,就更好理解了。
所谓的框架,是这样用的。
在几个已经写好的部分中加入自己的代码。让框架适用于自己的情况。
装饰器也是同理,:
装饰器极大程度重用了代码,简直写代码的好帮手
多个装饰器的执行顺序
执行顺序等效于