在以前我写过一篇博客,讲述了python的闭包和装饰器,python的装饰器一直是面试热点,也是python很重要的特性之一,不过我认为闭包是装饰器的基础,比装饰器拥有更宽广的概念和做用,因此若是面试官问我关于装饰器的问题,我都会从闭包的角度去分析装饰器,关于这个大块面试官问了我以下几个问题:什么是装饰器?什么是闭包?闭包和装饰器的做用?闭包和装饰器的使用场景?下面从这几个问题出发,在前一篇博客的基础之上更加深入的探讨关于闭包和装饰器的知识html
关于闭包的概念,我从网上找了以下几种说法:python
上面的话语基本涵盖了闭包的特性,关于这些语句的理解,我仍是先列举一个很是简单的例子:面试
# coding="utf-8" def fun(msg): def nested_fun(): print msg return nested_fun new_fun = fun("i like python") new_fun()
上面的代码首先定义了一个函数fun,在这个函数之中再定义了一个嵌套函数,以后返回了这个函数,在这个函数以外,从新将fun函数包括msg参数赋值给了new_fun,以后执行new_fun()函数,运行这段代码,能够发如今console中打印出了i love python这句话。上面的代码有两个注意点:1.函数也是一种对象,能够做为参数返回和传递;2.new_fun=fun("i like python")这句代码实际上是将new_fun指向了fun函数的返回值nested_fun函数,在执行new_fun函数的时候其实在执行了nested_fun函数,在这个函数中打印出的msg对象其实来自于上层函数,并非本身的本地变量,为何还会打印出来呢?因此这就是闭包,根据这个例子能够很好的体会上面列出的几种说法。
在python中闭包所知足的条件为:闭包
装饰器和闭包能够实现必定的封装功能,将函数或者变量封装起来,同时利用他们能够减小代码冗余,减小一些重复工做量。下面举一个例子,若是如今咱们想实现一个简单的乘法函数,好比times2(n)函数就是给n*2,times5(n)实现给n乘以5,这个功能可使用默认值很容易的实现,代码以下:app
def times2(n, x=2): return n * x print times2(3)
可是这有个明显的缺点,每一个times()函数都须要进行定义细节,如今能够用闭包来实现,代码以下:ide
def multiplier(n): def multi(x): return x * n return multi times2 = multiplier(2) times5 = multiplier(5) print times2(4) print times5(4)
这段代码的美妙你们能够好好体会一下。
说完了闭包,再说一说装饰器,装饰器就是用函数或者类去封装(装饰)另外一个对象,装饰器支持和被封装的对象相同的接口,因此被装饰的对象甚至感受不到本身被装饰了,在python中,装饰器更多的是一个函数将另外一个函数做为参数,他会利用闭包来实现整个装饰功能,和上面举得闭包的例子不一样的是,装饰器利用的是闭包能够捕获函数。
装饰器的经常使用场景以下:函数
下面简单的列举一个记录函数行为的装饰器的使用:es5
def logging(func): def wrapper(*args, **kwargs): res = func(*args, **kwargs) print func.__name__, args, kwargs return res return wrapper @logging def fib(n): if n == 1 or n == 0: return 1 return fib(n-1) + fib(n-2) print fib(10)
上面的装饰器代码实现了打印被装饰的函数的执行状况,你们能够本身运行。code
语言的美会获得承认和传播,好比lamdba函数,了解了语言的特性以后,能够极大的提升工做效率,增长代码的美感,提升代码的健壮性。htm