python 闭包与装饰器的关系_Python的闭包与装饰器

一、python的函数作用域

python的函数作用域的含义,简而言之,即函数执行时变量所在的作用域。在python中,共有四种函数作用域,分别为函数内部(local)、函数内部与函数内嵌函数之间(enclosing)、全局(globle)和python内置作用域(built in)。函数被调用时,解释器会先后在以上四种作用域寻找变量。即(L>>E>>G>>B)

解释一下四种作用域各是什么意思:

var1 = 10

def out_func(var2):

def in_func(var3):

print(sum([var1, var2, var3]))

return in_func

f = out_func(20)

f(30)#返回结果为10+20+30=60

在这段代码中,执行函数f(及内嵌函数in_func)时,需要使用变量var1,var2,var3以及函数sum,这四个变量的作用域分别为全局,闭包(enclosing),内部以及python内置作用域。

二、闭包

闭包的概念:内部函数中对enclosing作用域的变量进行引用。

在上面的例子中,内部函数调用了enclosing变量var2,即为闭包。

python中,函数也是一种对象,具有属性和方法,也有内存空间。

具体执行过程是这样的,在我们调用了外部函数out_func后,并将返回结果赋值给f。就给f变量和var2变量各分配了一块内存空间,f变量的内存空间的内容为函数in_func,var2内存空间的内容为20。由于in_func调用了enclosing变量var2,所以在out_func执行完之后,var2变量并没有销毁,而是作为in_func的属性保留下来。

三、闭包的用处

闭包的意义主要有两方面:代码的复用和封装。在这里因为要和装饰器联系起来,我们仅介绍代码的复用的功能。

如上文所述,如果var2不再是一个数值,而是一个函数func,那么我们就可以实现对应每一个函数func都可以经过内部函数的装饰形成一个新的函数。这样如果我们需要大量具有某些相同功能或者逻辑的函数就可以不用反复创建,这样不仅可以减少代码量,也更容易维护。

例如:我们想为所有函数添加一个能够自动显示其属性的功能。

def dec(func):

def in_func(*args):

print(dir(func))

return func(*args)

return in_func

f1 = dec(sum)

f2 = dex(max)

n1 = f1([1,2,3]) #将会将in_func的所有属性显示出来

n2 = f2([1,2,3]) #将会将in_func的所有属性显示出来

其函数调用过程与上述过程完全一致,我们就不再具体分析。

四、装饰器

知道了闭包之后,装饰器就很容易理解了。在上述内容中我们为所有函数都“装饰”了一个功能,即显示其所有属性。

python中设计了一种语法糖,我们可以在上述函数中不调用dec函数创建函数,而是采用@dec这种形式。即:

def dec(func):

def in_func(*args):

print(dir(func))

return func(*args)

return in_func

@dec

def avg(*args):

return sum(*args)/len(*args)

n = avg([1,2,3])

五、最后

欢迎大家评论留言,也希望可以和大家广泛讨论各种各样的技术知识。

谢谢!

你可能感兴趣的:(python,闭包与装饰器的关系)