import importlib


DEFAULT_SETTINGS = {
    "packageNames": [
        "framework.module.Interceptor",
    ]
}

class InterceptorChain(object):

    _interceptors = []

    def __init__(self, packageNames = None):
        if packageNames is None:
            self.packageNames = DEFAULT_SETTINGS.get("packageNames")
        else:
            self.packageNames = packageNames

    def doFefore(self, request):
        for interceptor in self._interceptors:
            interceptor().process_request(request)

    def addInterceptor(self, interceptor):
        self._interceptors.append(interceptor)

    def loaderPlugin(self):
        for packageName in self.packageNames:
            methodName = packageName[packageName.rindex(".") + 1:]
            moduleName = packageName[:packageName.rindex(".")]

            try:
                module = importlib.import_module(moduleName)
                if hasattr(module, methodName):
                    clazz = getattr(module, methodName)
                    self._interceptors.append(clazz)
            except ImportError as e:
                print(e)

    def doAfter(self, request, response):
        size = len(self._interceptors) - 1
        while size >= 0:
            self._interceptors[size]().process_response(request, response)
            size -= 1

    def process(self, func, req):
        self.loaderPlugin()
        self.doFefore(req)
        if callable(func):
            resp = func(req)
            self.doAfter(req, resp)
            return resp
        raise TypeError("func is not a callable obj")


def index(request):
    return "req"

chain = InterceptorChain()
print(chain.process(index, "name"))

2、拦截对象

class Interceptor(object):

    def process_request(self, request):
        print(request + " req")

    def process_response(self,request, response):
        return response + " Interceptor"