Create a wrapper class to call a pre and post function around existing functions?

前端 未结 2 950
天涯浪人
天涯浪人 2020-12-05 05:56

I want to create a class that wraps another class so that when a function is run through the wrapper class a pre and post function is run as well. I want the wrapper class t

相关标签:
2条回答
  • 2020-12-05 06:16

    You're almost there, you just need to do some introspection inside __getattr__, returning a new wrapped function when the original attribute is callable:

    class Wrapper(object):
        def __init__(self,wrapped_class):
            self.wrapped_class = wrapped_class()
    
        def __getattr__(self,attr):
            orig_attr = self.wrapped_class.__getattribute__(attr)
            if callable(orig_attr):
                def hooked(*args, **kwargs):
                    self.pre()
                    result = orig_attr(*args, **kwargs)
                    # prevent wrapped_class from becoming unwrapped
                    if result == self.wrapped_class:
                        return self
                    self.post()
                    return result
                return hooked
            else:
                return orig_attr
    
        def pre(self):
            print ">> pre"
    
        def post(self):
            print "<< post"
    

    Now with this code:

    number = Wrapper(Simple)
    
    print "\nCalling wrapped 'one':"
    number.one()
    
    print "\nCalling wrapped 'two':"
    number.two("2")
    

    The result is:

    Calling wrapped 'one':
    >> pre
    one
    << post
    
    Calling wrapped 'two':
    >> pre
    two2
    << post
    
    0 讨论(0)
  • 2020-12-05 06:31

    I have just noticed in my original design there is no way of passing args and kwargs to the wrapped class, here is the answer updated to pass the inputs to the wrapped function...

    class Wrapper(object):
    def __init__(self,wrapped_class,*args,**kargs):
        self.wrapped_class = wrapped_class(*args,**kargs)
    
    def __getattr__(self,attr):
        orig_attr = self.wrapped_class.__getattribute__(attr)
        if callable(orig_attr):
            def hooked(*args, **kwargs):
                self.pre()
                result = orig_attr(*args, **kwargs)
                self.post()
                return result
            return hooked
        else:
            return orig_attr
    
    def pre(self):
        print ">> pre"
    
    def post(self):
        print "<< post"     
    
    0 讨论(0)
提交回复
热议问题