python内部函数、闭包共同之处在于都是以函数作为参数传递到函数,不同之处在于返回与调用有所区别。

1、python内部函数

python内部函数示例:

def test(*args):
def add(*args): # 显示的调用外部函数的参数
return args
return add(*args) # 返回内部函数的直接调用
运行结果如下:
test(1,2,3)
(1,2,3)

内部函数直接引用外部函数参数,外部函数test显示的返回内部函数add的调用。

当需要在函数内部多次执行复杂任务时,内部函数非常有用,从而避免了循环和代码的堆叠重复。

2、python闭包

内部函数可以看作是一个闭包。闭包是一个可以由另一个函数动态生成的函数,并且可以改变和存储函数外创建的变量的值。

python闭包示例:

def test(a):
def add(): # 没用引用外部函数的参数
return "it's a callable %s" % a # 直接在内部函数使用外部函数的参数
return add # 返回内部函数本身,不返回内部函数调用
运行结果如下:
a1 = test(1) # 动态生成的一个可以记录外部变量的函数
a1() # 调用此函数
it's a callable 1
test(1)() # 本身调用过程,先动态生成一个函数再进行调用
it's a callable 1

3、python装饰器

装饰器实质上是一个函数,它把一个函数作为输入并且返回另外一个函数,在装饰器中,通常使用下面这些python技巧:

*args 和 **kwargs

闭包

作为参数的函数

python装饰器示例:

def test(func): # 将函数作为参数进行传递
def add(*args,**kwargs):
print “it's a d”
return func(*args,**kwargs) # 内部函数进行相关操作以后,返回传递函数的调用
return add
def func(a,b):
return a+b
运行结果如下:
test(func) # 将func作为函数传递进test函数进行装饰
 # 装饰后的函数,类似闭包
test(func)(1,2) # 显示的对装饰后的函数进行调用
it's a d # 中间被装饰的过程被print出来
3

更简单的方法调用装饰器

@test # 同一个函数可以调用多个装饰器,执行过程中不分先后顺序

def func(a,b):
return a+b

无论传入test()的函数func是什么,装饰器都会返回一个新的函数,其中包含test增加的额外语句。

实际上,装饰器并不需要执行函数func中的代码,只是在结束前函数add调用函数func以得到的func返回的结果和附加代码的结果

装饰器本身需要传递参数的时候:

def test(cmd): # 将参数传递
def exc(func): # 第二步进行函数作为参数传递
def add(*args,**kwargs):
print "it's a %s" % cmd
print "begin"
return func(*args,**kwargs)
return add
return exc
运行结果如下:
test('haha')
test('haha')(func)(1,2) # 调用装饰器返回结果
it's a haha
begin
3

更简单的方法调用

@test('haha') # test函数进行了参数传递

def func(a,b):
return a+b

python装饰器注意事项:

对func进行装饰以后,func的函数命名空间发生了变化

执行 func.__name__

add

如何指向原来的命名空间呢?python自带了functools库直接调用则行

import functools
def test(func):
@functools.wraps(func)
def add(*args,**kwargs):
print "it's a decorator"
return func(*args,**kwargs)
return add
@test
def func(a,b):
return a+b
再次运行,查看命名空间
func.__name__
func # 返回了本身