Python 返回函数_闭包_装饰器

时间:2022-07-27 22:45:14

廖雪峰Python教程笔记

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。我们来实现一个可变参数的求和。通常情况下,求和的函数是这样定义的:
def calc_sum(*args):        #这个是普通函数定义,变量取值对象是取列表内的元素
    ax = 0
    for n in args:
        ax = ax + n
    return ax

但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数:
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:         # 这一行表示的意思是,sum函数可以取lazy_sum的参数用
            ax = ax + n
        return ax
    return sum         #这一行,返回的是sum这个函数值

当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数:
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
<function lazy_sum.<locals>.sum at 0x101c6ed90>
调用函数f时,才真正计算求和的结果:
>>> f()
25

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以上是教程里的话,由于教程里是在交互环境里打的,所以如果我们在编程环境里看的话,是打印不出结果的,我就自己添加了测试语句2句。

print (f)   #这行打印出来的是  <function lazy_sum.<locals>.sum at 0x101c6ed90>

print (f()) #这行打印出来的是 25 ,所以说,只有真正调用f()的时候,才会打印出结果,不然只是生成函数.


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面讲 <闭包>

闭包的概念停一下......先看后面的,脑子搞得受不了了,先看后面的章节,等实战的时候再来想办法吃透....



下午看返回函数和闭包还在头疼欲裂....准备先搁置了看装饰器的....

结果发现闭包和装饰器是一伙的....没办法,还是回过头来看闭包...总算是看了其他前辈整理的一些资源,算是对闭包有些理解了,赶紧做下笔记.

闭包还没完全整理好思路,反过来讲,先讲装饰器.

如下例子:

1 def log(func):                                                      #定义了log函数,但是()内是调用了另外的函数,在下面通过func.name可以看到,func就是指代被嵌套进来的函数的名字.
2    def wrapper(*args, **kw):                            # 对于函数的取值,可以取任何值, *args为列表元素取值, **kw为字典元素取值
3         print('call %s():' % func.__name__)     #打印一句话 call %s():           打印出来的,就是func.__name__   ,其实就是你往里面送什么函数func,他提取什么名字
4         return func(*args, **kw)                          # 这句返回,返回的是,通过func函数通过提取到的变量,返回出来的结果.
5     return wrapper


继续往下看,如果有个简单的函数定义如下

def now():
print('2015-3-25')

当我们要调用装饰器log的时候,就需要在now函数的上面,增加@log的命令,代表将now这个函数嵌套进装饰器log进行使用.

@log
def now():
    print('2015-3-25')

好了,关键搞脑子的地方来了.

其实我们就可以把上述的例子,嵌套进装饰器,写成

def log(now):
    def wrapper(*args, **kw):
        print('call %s():' % now.__name__)
        return now(*args, **kw)
    return wrapper

def now():

print ('2015-3-25')

就等于启动程序后,先打印了第三行的

call now():



把@log放到now()函数的定义处,相当于执行了语句:
now = log(now)

这是我对装饰器的理解,还很薄弱....待后期实践后加强,不过至少不懵逼了....闭关回头再写.