decorate all function in all module

需求:api

有package db_api,其下有不少 module 如 plane.py ship.py ufo.py。這些module內定義了方法如 plane.fly(), ship.float(),ufo.siu()。如今但願有一個裝飾器來給裝飾這些函數,讓其打印log,log中包含調用的參數以及return。app

解決辦法函數

首先定義 decoratorcode

def db_log(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        func_name = str(func) if func else ''
        log_args = str(args) if args else ''
        log_kwargs = str(kwargs) if kwargs else ''
        eventLog.info("call %s" % func_name)
        eventLog.info("args are %s" % log_args)
        eventLog.info("kwargs are %s " % log_kwargs)

        ret = func(*args, **kwargs)
        log_ret = str(ret) if ret else ''
        eventLog.info("ret are %s" % log_ret)
        return ret

    return wrapper

這沒什麼問題,問題是,接下來你要手動的去裝飾以前的每個方法如 fly 等。 這裏咱們用一段代碼動態的patch 這些函數ip

在db_api/init.py 中會import 全部moduleget

import plane
import ufo
import ship

而後用下面的代碼動態裝飾it

for module_obj in dir():
    if isinstance(eval(module_obj),type(plane)) and eval(module_obj).__package__ == 'db_api':
        # Patch call ables
        module_obj = eval(module_obj)
        for func_obj in dir(module_obj):
            if callable(getattr(module_obj, func_obj)) and not func_obj.startswith('_') and isinstance(getattr(module_obj, func_obj),type(lambda x: x)):
                # func_obj = db_log(func_obj)
                setattr(module_obj,func_obj,db_log(getattr(module_obj, func_obj)))
相關文章
相關標籤/搜索