分享

Python装饰器与面向切面编程

 昵称QAb6ICvc 2013-02-17

Python装饰器与面向切面编程

(2011-12-15 09:41:09)
标签:

python

装饰器

面向

切面

编程

it

分类: 语言

1. 概述

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

Python从语法层为我们提供了非常好的实现装饰模式的方法。

2. 动机

如果不使用python装饰器语法的话,我们如果想转换一个函数(或换句话说,给函数加上装饰器,例如将一个普通函数转变成类函数)的话,代码看起来是这样子的:

'''

Created on 2011-12-14

 

@author: Ahan

'''

class Foo(object):

    def foo(self):

        print("foo is called")

        pass

    #Turn the method foo to class method

    foo classmethod(foo)

 

if __name__ == '__main__':

    Foo.foo()

pass

 

可以想象,函数一多,代码的可读性就大大下降了。Python提供了一个另一种优雅的方法来解决这个问题。修改后的代码如下:

'''

Created on 2011-12-14

 

@author: Ahan

'''

class Foo(object):

    #Turn the method foo to class method

    @classmethod

    def foo(self):

        print("foo is called")

        pass

if __name__ == '__main__':

    Foo.foo()

pass

 

代码量减少了,可读性也强了,函数的特性也很直观。

3. 当前语法

当前Python的装饰器语法如下:

@dec2

@dec1

def func(arg1, arg2...):

pass

 

上面的代码相当于:

 

def func(arg1, arg2, ...):

    pass

func dec2(dec1(func))

 

4. 装饰器的更多用法示例

我们可以使用Python装饰器来更加直接了当地使用staticmethod() classmethod()内置函数,但装饰器的作用远不止于此。

1.例如我们要定义一个函数,当程序退出的时候调用此函数。

def onexit(f):

    import atexit

    atexit.register(f)

    return f

 

@onexit

def func():

...

注意在真实场景中我们可能不会这么做,上面代码只是用作示例。

2.使用Python装饰器实现单例模式。

def singleton(cls):

    instances {}

    def getinstance():

        if cls not in instances:

            instances[cls] cls()

        return instances[cls]

    return getinstance

 

@singleton

class MyClass:

    ...

3.给函数添加属性。

def attrs(**kwds):

    def decorate(f):

        for in kwds:

            setattr(f, k, kwds[k])

        return f

    return decorate

 

@attrs(versionadded="2.2",

       author="Guido van Rossum")

def mymethod(f):

    ...

4.声明类实现了某些接口。

def provides(*interfaces):

     """

     An actual, working, implementation of provides for

     the current implementation of PyProtocols.  Not

     particularly important for the PEP text.

     """

     def provides(typ):

         declareImplementation(typ, instancesProvide=interfaces)

         return typ

     return provides

 

class IBar(Interface):

     """Declare something about IBar here"""

 

@provides(IBar)

class Foo(object):

        """Implement something here..."""

 

参考资料:http://www./dev/peps/pep-0318/#examples 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多