taoCMS是基于php+sqlite/mysql的国内最小(100Kb左右)的功能完善、开源免费的CMS管理系统

Python装饰器与面向切面编程

2013-06-17

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.python.org/dev/peps/pep-0318/#examples 

类别:技术文章 | 阅读:215728 | 评论:0 | 标签:python 装饰器

想收藏或者和大家分享这篇好文章→

“Python装饰器与面向切面编程”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

taoCMS发布taoCMS 3.0.2(最后更新21年03月15日),请大家速速升级,欢迎大家试用和提出您宝贵的意见建议。

捐助与联系

☟请使用新浪微博联系我☟

☟在github上follow我☟

标签云