函数——闭包和装饰器

一、闭包

python中的闭包从表现形式上定义:

如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被认为是闭包。

定义在外部函数内的但由内部函数引用或者使用的变量被称为自由变量。

闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你,返回的函数B就叫做B包。

你在调用A时传递的参数就是自用变量

def fun(name):
    def inner_func(age):
        print(name,age)  #引用外部函数name,那么也叫做内部函数,即使那么离开了inner_func这个函数,那么依旧存在,这就是自由变量。
    return inner_func
bb = fun('kebi')
bc = fun('maoxian')
bb(26)
bc(26)   #传递age参数。
bb(18)
bc(18)
执行结果:
kebi 26
maoxian 26
kebi 18
maoxian 18

在调用fun的时候就产生了一个闭包——inner_fun,并且该包持有自由变量name。

fun是一个函数,包含一个参数name,这个函数里面又定义了一个函数inner_func,其中的一个变量是外部函数fun的参数name。

也就是说外部传递过来的参数已经和inner_func这个函数捆绑到了一起,形成了一个新的函数。

我们可以把那么看作是inner_func的一个配置信息,配置的信息不同,函数的功能就不同。

虽然bb和bc都是fun生成的,但是由于配置参数不同,也就得到了不同的结果。这就是闭包的功能。

判断闭包的方法:__closure__

def fun(name):
    def inner_func(age):
        print(name,age)
    print(inner_func.__closure__)
    return inner_func
bb = fun('kebi')
bb(26)

结果:
(<cell at 0x00000241F04F5498: str object at 0x00000241F058D8F0>,)
kebi 26

#返回的结果是cell元素则是闭包,否则不是闭包

二、装饰器

之所将装饰器放在闭包后面,是因为装饰器要用到闭包。

其实,装饰器,就是一个闭包,同时也是一个函数。

装饰器是在函数调用之上的修饰,这些修饰仅是当声明一个函数或者方法的时候,才会额外的调用。

简单的说就是对函数(参数,返回值等)进行加工处理,生成一个功能增强版的一个函数。

装饰器的语法以@开头,接着是装饰器的名字和可选参数,紧跟着被装饰器修饰的函数和装饰函数的可选参数。

@decorator(dec_opt_args)  ——》@装饰器的名字(可选参数)

def funcdecorator(func_opt_args)——》def 被装饰的函数(可选参数)

def makebold(fn):  #makeitalic(hello())是参数
    def wrapped():
        return "<b>" + fn() + "</b>"  #自由变量的调用
    return wrapped

def makeitalic(fn):   #hello()函数是参数
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped

@makebold  #在装饰
@makeitalic  #先装饰       其实整个是这样的:makebold(makeitalic(hello())) 一层一层参数传入,一层一层装饰
 def hello() return "hello world" print(hello()) 执行结果: <b><i>hello world</i></b>

应该说上面这个例子非常好的展示了装饰器的功能。

装饰器就是闭包,为什么要这样说了,因为闭包有至少两个函数,一个变量。二装饰器就是有三个函数,装饰器的参数就是第三个函数,也就是闭包中的自由变量,inner再比闭包中是内部函数。再装饰器中只是装饰器的一部分。

原文地址:https://www.cnblogs.com/yangmingxianshen/p/7769426.html