python 装饰器、内部函数、闭包简单理解

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

一、python内部函数

python内部函数示例:闭包

def test(*args):
    def add(*args):         #  显示的调用外部函数的参数
        return args
    return add(*args)       #  返回内部函数的直接调用

运行结果以下:
test(1,2,3)
(1,2,3)    

 
内部函数直接引用外部函数参数,外部函数test显示的返回内部函数add的调用。
当须要在函数内部屡次执行复杂任务时,内部函数很是有用,从而避免了循环和代码的堆叠重复。函数

 

二、python闭包

内部函数能够看做是一个闭包。闭包是一个能够由另外一个函数动态生成的函数,而且能够改变和存储函数外建立的变量的值。blog


python闭包示例:
cmd

def test(a):
    def add():                                #  没用引用外部函数的参数
        return "it's a callable %s" % a       #  直接在内部函数使用外部函数的参数
    return add                                #  返回内部函数自己,不返回内部函数调用

运行结果以下:
a1 = test(1)           # 动态生成的一个能够记录外部变量的函数
<function __main__.add>

a1()                   # 调用此函数
it's a callable 1

test(1)()              # 自己调用过程,先动态生成一个函数再进行调用
it's a callable 1

 

三、python装饰器

装饰器实质上是一个函数,它把一个函数做为输入而且返回另一个函数,在装饰器中,一般使用下面这些python技巧:it

  • *args 和 **kwargsio

  • 闭包function

  • 做为参数的函数class

python装饰器示例:test

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函数进行装饰
<function __main__.add>   # 装饰后的函数,相似闭包

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')
 <function __main__.exc>
 
 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                  # 返回了自己
相关文章
相关标签/搜索