【问题标题】:Intercept method calls in Python在 Python 中拦截方法调用
【发布时间】:2011-02-11 20:43:41
【问题描述】:

我正在用 python 实现一个 RESTful Web 服务,并想通过拦截函数调用并记录它们的执行时间等来添加一些 QOS 日志记录功能。

基本上我想到了一个所有其他服务都可以继承的类,它会自动覆盖默认方法实现并将它们包装在一个记录器函数中。实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: python


    【解决方案1】:

    这样的?这隐含地为您的方法添加了一个装饰器(如果您愿意,也可以基于此创建一个显式装饰器):

    class Foo(object):
        def __getattribute__(self,name):
            attr = object.__getattribute__(self, name)
            if hasattr(attr, '__call__'):
                def newfunc(*args, **kwargs):
                    print('before calling %s' %attr.__name__)
                    result = attr(*args, **kwargs)
                    print('done calling %s' %attr.__name__)
                    return result
                return newfunc
            else:
                return attr
    

    当你现在尝试类似:

    class Bar(Foo):
        def myFunc(self, data):
            print("myFunc: %s"% data)
    
    bar = Bar()
    bar.myFunc(5)
    

    你会得到:

    before calling myFunc
    myFunc:  5
    done calling myFunc
    

    【讨论】:

    • 不应该是 retval = attr(*args, **kwargs) ... return retval 以防方法返回什么?
    • 如果Foo 不直接从object 继承,那么您可能需要调用super(Foo, self).__getattribute__ 而不是object.__getattribute__,以便尊重继承链。
    • @FlorianBrucker:使用super 并正确理解 MRO 充其量是棘手的,我更喜欢提供显式基类,当然在这样的示例中。
    • @KillianDS 我坚决支持 FlorianBrucker 在这一点上,object.__getattribute__ 不是 pythonic 并且会增加混乱。
    • @Jay 它有什么非pythonic? “显式优于隐式”呢?
    【解决方案2】:

    如果你为每个函数写一个装饰器会怎样?这是python's wiki 的示例。

    您是否使用任何网络框架来提供您的网络服务?还是你手工做所有事情?

    【讨论】:

    • 这是一个例子,了解它是如何工作的。根据定义,示例并不是什么神奇的东西
    猜你喜欢
    • 2012-04-01
    • 2021-09-16
    • 2014-10-11
    • 1970-01-01
    • 2011-07-07
    • 2015-08-14
    相关资源
    最近更新 更多