[python]python装饰器

来源:互联网 发布:天猫和淘宝哪个好 编辑:程序博客网 时间:2024/04/26 11:51



关于装饰器的详细描述在PEP-318有详尽的描述

https://www.python.org/dev/peps/pep-0318/

装饰器是在函数调用之上的修饰,这些修饰是仅当声明一个函数或者方法时才会应用的额外调用。

装饰器以@开头,接着是装饰器的名字和可选的参数,紧接着装饰器声明的是被修饰的函数和装饰函数的可选参数。看起来是这样样子

@decorator (dec_opt_args)def func2Bdecorated (func_opt_args):    pass

了解修饰器之前,我们先来了解下他是如何产生的。当静态方法和类方法在2.2被加入到python时,实现是这样的:

class MyClass (object):    def staticFoo ():        pass    staticFoo = staticmethod(staticFoo)

def 后面跟着一行staticFoo = staticmethod(staticFoo)是有多臃肿,但是如果引入装饰器,就可以这样替换上面的代码:

class MyClasss (object):    @staticmethod    def staticFoo():        pass

大概你已经猜到装饰器的基本使用方法了,我们再来看一个例子:

@g@fdef foo():    pass

如果用数学组合来表示的话,他就是这样的:(g · f) (x) = g( f(x) )。因此上面的代码等价于:

def foo():    passg( f(foo) )

装饰器的语法开始的确会让人觉得凌乱,原因就在于什么时候使用带参数的装饰器,在没有参数的情况下,一个装饰器看起来十分简单:

@decodef foo():    pass

很直接的知道他相当于

def foo():    passfoo = deco(foo)

但如果是带有参数的装饰器呢:

@deco1(deco_args)def foo():    pass

它相当于:
def foo():    passfoo = deco1(deco_args)(foo)

实际上deco1接受了deco_args参数然后返回一个函数对象,这个函数对象就是foo真正的装饰器。简单来说,我们可以把deco1(deco_argc)看成一个整体,用deco来代替,这样就变成了上面那个不带参数的装饰器,然后这个deco的装饰器实际是一个函数执行后的返回对象,不过这都不重要了。如果你理解上面的技巧,我们再把这个例子变化一下:

@deco1(deco_arg)@deco2def func():    pass

相当于:

deco1(deco_arg)(deco2(func))

其实就这么简单,像数学函数一样,嵌套嵌套嵌套。


说了这么久,那么到底什么是装饰器?装饰器实际就是一个接受函数对象为参数的函数。看几个装饰器例子,

1.定义一个退出程序时执行的函数

def onexit(f):    import atexit    atexit.register(f)    return f@onexitdef func():    ...

2.
# -*- coding:gbk -*-
'''示例3: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
但发现新函数只在第一次被调用,且原函数多调用了一次'''
 
def deco(func):
    print("before myfunc() called.")
    func()
    print("  after myfunc() called.")
    return func
 
@deco
def myfunc():
    print(" myfunc() called.")
 
myfunc()
myfunc()



0 0
原创粉丝点击