本文介绍了Python:使用前置和后置方法包装方法调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实例化A类(我是从某人导入的)否则,我将无法对其进行修改).

I am instantiating a class A (which I am importing from somebodyelse, so I can't modify it) into my class X.

有没有一种方法可以拦截或包装对A中方法的调用?也就是说,我可以在下面的代码中调用

Is there a way I can intercept or wrap calls to methods in A?I.e., in the code below can I call

x.a.p1()

并获取输出

X.pre
A.p1
X.post

许多TIA!

class A:
    # in my real application, this is an imported class
    # that I cannot modify
    def p1(self): print 'A.p1'

class X:
    def __init__(self):
        self.a=A()
    def pre(self): print 'X.pre'
    def post(self): print 'X.post'

x=X()
x.a.p1()

推荐答案

这是我和我的同事提出的解决方案:

Here is the solution I and my colleagues came up with:

from types import MethodType

class PrePostCaller:
    def __init__(self, other):
        self.other = other

    def pre(self): print 'pre'
    def post(self): print 'post'

    def __getattr__(self, name):
        if hasattr(self.other, name):
            func = getattr(self.other, name)
            return lambda *args, **kwargs: self._wrap(func, args, kwargs)
        raise AttributeError(name)

    def _wrap(self, func, args, kwargs):
        self.pre()
        if type(func) == MethodType:
            result = func( *args, **kwargs)
        else:
            result = func(self.other, *args, **kwargs)
        self.post()
        return result

#Examples of use
class Foo:
    def stuff(self):
        print 'stuff'

a = PrePostCaller(Foo())
a.stuff()

a = PrePostCaller([1,2,3])
print a.count()

赠予:

pre
stuff
post
pre
post
0

因此,在创建对象的实例时,请使用PrePostCaller对象包装它.之后,您可以继续使用该对象,就像它是包装对象的实例一样.使用此解决方案,您可以按实例进行包装.

So when creating an instance of your object, wrap it with the PrePostCaller object. After that you continue using the object as if it was an instance of the wrapped object. With this solution you can do the wrapping on a per instance basis.

这篇关于Python:使用前置和后置方法包装方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 09:43