python學習之aop裝飾模式


實際開發過程當中可能要對某些方法或者流程做出改進,添加監控,添加日志記錄等
所以我們要去改動已有的代碼,自己的或者別人的,但改動后測試不周會引發不可控的異常,aop 模式解決了這類問題
引發重復代碼大量積累,裝飾器解決了些類問題

 1:基礎篇

import functools

#采用functools.wraps的目的是為了使裝飾器返回的類型始終是func的類型,否則將返回嵌套高階函數的中的類型,例如返回的是wraper
#采用參數*args ,**kw是解決函數多參數的問題
def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print 'call %s():' % func.__name__
        return func(*args, **kw)
    return wrapper


#修飾器參數的情況
def logger(pram):
    def log(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print 'call %s(): and parsms is %s' %(func.__name__,pram);
            return func(*args, **kw);
        return wrapper;
    return log;


@log
def showMesage(name,age):
    print("my name is {0} and my age is {1}".format(name,age));


@logger("hello")
def getMessage(name,age):
    print("my name is {0} and my age is {1}".format(name,age));

#添加多個修飾器來拓展所需的功能
@log
@logger("hello15466")
def recieveMessage(name,age):
    print("my name is {0} and my age is {1}".format(name,age));


if __name__=='__main__':
    showMesage("ddd",21);
    getMessage("aaa",43);
    recieveMessage("ccc",34);

 2:通過一個實用性的示例來繼續描述下裝飾器的使用場景,這次我將裝飾器提取到類中,需要調用的地方通過類的引用來調取

下面這個示例演示的是一個監控程序運行時間的,如下:

一: 建立一個監控類[monitor.py]:

import functools;
import time;

class monitor:
    @staticmethod
    def startmonitor():
        return time.clock();

    @staticmethod
    def endmonitor():
        return time.clock();



def listener(listen):
    def log(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            startime=listen.startmonitor();
            f=func(*args, **kw);
            endtime=listen.endmonitor();
            print("total time is {0}".format(startime-endtime));
            return  f;
        return wrapper;
    return log;

二:在需要使用的地方來調用監控

from  monitor import  *;

@listener(monitor)
def getinfo():
    print("hello ,welcome!");

if __name__=="__main__":
    getinfo();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM