廖雪峰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)
这是我对装饰器的理解,还很薄弱....待后期实践后加强,不过至少不懵逼了....闭关回头再写.