在 Python 中拦截方法调用
Posted
技术标签:
【中文标题】在 Python 中拦截方法调用【英文标题】:Intercept method calls in Python 【发布时间】:2021-06-07 17:01:29 【问题描述】:我正在用 python 实现一个 RESTful Web 服务,并想通过拦截函数调用并记录它们的执行时间等来添加一些 QOS 日志记录功能。
基本上我想到了一个所有其他服务都可以继承的类,它会自动覆盖默认方法实现并将它们包装在一个记录器函数中。实现这一目标的最佳方法是什么?
【问题讨论】:
【参考方案1】:如果你为每个函数写一个装饰器会怎样?这是python's wiki 的示例。
您是否使用任何网络框架来提供您的网络服务?还是你手工做所有事情?
【讨论】:
这是一个例子,了解它是如何工作的。根据定义,示例并不是什么神奇的东西【参考方案2】:这样的?这隐含地为您的方法添加了一个装饰器(如果您愿意,也可以基于此创建一个显式装饰器):
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? “显式优于隐式”呢?以上是关于在 Python 中拦截方法调用的主要内容,如果未能解决你的问题,请参考以下文章