如何拦截实例方法调用?

Vik*_*kas 12 python function call instance getattr

我正在寻找一种方法来拦截MyWrapper下面的类中的实例方法调用:

class SomeClass1:
    def a1(self):
        self.internal_z()
        return "a1"
    def a2(self):
        return "a2"
    def internal_z(self):
        return "z"

class SomeClass2(SomeClass1):
    pass

class MyWrapper(SomeClass2):

    # def INTERCEPT_ALL_FUNCTION_CALLS():
    #      result = Call_Original_Function()
    #      self.str += result  
    #      return result  


    def __init__(self):
        self.str = ''
    def getFinalResult(self):
        return self.str

x = MyWrapper()
x.a1()
x.a2()
Run Code Online (Sandbox Code Playgroud)

我想通过我的包装类拦截所有函数调用.在我的包装器类中,我想跟踪所有结果字符串.

result = x.getFinalResult()
print result == 'a1a2'
Run Code Online (Sandbox Code Playgroud)

Sha*_*kka 5

一些快速而肮脏的代码:

class Wrapper:
    def __init__(self, obj):
        self.obj = obj
        self.callable_results = []

    def __getattr__(self, attr):
        print("Getting {0}.{1}".format(type(self.obj).__name__, attr))
        ret = getattr(self.obj, attr)
        if hasattr(ret, "__call__"):
            return self.FunctionWrapper(self, ret)
        return ret

    class FunctionWrapper:
        def __init__(self, parent, callable):
            self.parent = parent
            self.callable = callable

        def __call__(self, *args, **kwargs):
            print("Calling {0}.{1}".format(
                  type(self.parent.obj).__name__, self.callable.__name__))
            ret = self.callable(*args, **kwargs)
            self.parent.callable_results.append(ret)
            return ret

class A:
    def __init__(self, val): self.val = val
    def getval(self): return self.val

w = Wrapper(A(10))
print(w.val)
w.getval()
print(w.callable_results)
Run Code Online (Sandbox Code Playgroud)

我猜可能不是很彻底,但可能是一个不错的起点.