示例代码6:
#coding=utf-8
def add(x, y):
return x + y
def sub(x, y):
return x - y
def apply(func, x, y):
return func(x, y)
print (apply(add, 2, 1)) #add函数作为apply函数的参数传递
print (apply(sub, 2, 1))
执行结果:
3
1
6.闭包:
定义:如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包。
一个函数返回的函数对象,这个函数对象执行需要依赖外部函数的变量值,这个时候函数返回的实际内容如下:
1.函数对象
2.函数对象执行需要使用的外部变量和变量值。
简而言之:闭包就是返回一个函数和一个函数执行所需要的外部变量。
示例代码7:
#coding=utf-8
def outer():
name = "python"
def inner() :
print (name) #函数使用了外部的name变量
return inner #返回函数对象
res = outer() #调用outer()方法,返回inner函数对象
res() #inner函数的对象+()=调用函数inner()
print (res.func_closure)# 查看函数包含哪些外部变量
#print (res()) #注意使用print打印返回结果为name值+inner函数默认返回值None
执行结果:
python
(<cell at 0x0000000002706CD8: str object at 0x0000000002708738>,) #外部变量是一个str类型
上例中的inner()函数就是一个闭包,它本身也是一个函数,而且还可以访问本身之外的变量。
每次函数outer被调用时,inner函数都会被重新定义,示例代码7每次返回的函数inner结果都一样,因为name没变。如下例所示,我们将函数稍微改动
一下,结果就不一样了。
示例代码8:
#coding=utf-8
def outer(name) :
def inner() :
print (name)
return inner
res1 = outer("python")
res2 = outer("Java")
res1()
res2()
执行结果:
python
java
学习了以上6个小知识点,下面开始学习装饰器。
装饰器的定义:
装饰器其实就是一个闭包,把一个函数当做参数后返回一个替代版函数。
装饰器分类:
装饰器分为无参数decorator和有参数decorator
无参数decorator:生成一个新的装饰器函数
有参数decorator:装饰函数先处理参数,再生成一个新的装饰器函数,然后对函数进行装饰。
装饰器的具体定义:
1、把要装饰的方法作为输入参数;
2、在函数体内可以进行任意的操作;
3、只要确保最后返回一个可执行的函数即可(可以是原来的输入参数函数,也可以是一个新函数)
装饰器学习七步法:
第一步:最简单的函数,准备附加额外功能
# -*- coding:utf-8 -*-
#最简单的函数,表示调用了两次函数
def myfunc():
print "myfunc() called."
myfunc()
myfunc()
执行结果:
myfunc() called.
myfunc() called.
第二步:使用装饰函数在函数执行前和执行后分别附加额外功能
# -*- coding:utf-8 -*-
'''示例2: 替换函数(装饰) ,装饰函数的参数是被装饰的函数对象,返回原函数对象。装饰的实质语句: myfunc = deco(myfunc)'''
def deco(func):
print ("before myfunc() called.") #在func()函数执行前附加功能,打印一句话
func() #被执行函数
print ("after myfunc() called.") #在func()函数执行后附加功能,打印一句话
return func
def myfunc():
print ("myfunc()called.")
new_myfunc = deco(myfunc) #表示调用参数为myfunc函数对象的deco()函数,结果返回func函数对象并赋值给myfunc
new_myfunc() #表示调用myfunc函数
new_myfunc() #表示调用myfunc函数
结果:
before myfunc() called.
myfunc()called.
after myfunc() called.
myfunc()called.
myfunc()called.
解析:
1.myfunc = deco(myfunc)执行结果:
before myfunc() called.
myfunc()called.
after myfunc() called.
2.第一次调用myfunc()执行结果:
myfunc()called.
3.第二次调用myfunc()执行结果:
myfunc()called.