最近有个以前培训班的学员问我Python有没有类似与Java动态代理的机制?他想通过类似Java动态代理的机制对类的所有方法调用日志功能。查了一下,虽然Python官方没有提供这个功能,但是作为一门提供了反射机制的动态语言,我们妥妥的可以自己撸一个啊。
如果再阅读本文有什么不清楚的地方,建议先阅读廖雪峰老师教程的以下章节:
- 函数:函数的参数(主要看可变参数)
- 函数式编程:装饰器
- 面向对象编程
首先我们复习一下装饰器的实现,装饰器本质是一个高阶函数,通过封装对原油函数的调用,增强了原有函数的功能。
def log(func):
def wrapper(*args, **kws):
print('Call %s' % func.__name__)
ret = func(*args, **kws)
print('Finish call %s' % func.__name__)
return ret
return wrapper
@log
def add(x, y):
return x + y
z = add(1, 2)
print(z)
'''
输出如下:
Call add
Finish call add
3
'''
以上例子我们是通过装饰器增强了一个函数,那么如何通过装饰器增强一个类的所有方法呢?在展开具体实现之前,我们先介绍一下以下两个知识点:
- ()方法,如果你曾经接触过C++的仿函数概念,那么对重载()操作符不陌生。Python提供了__call__方法实现这个功能。
class Sample:
def __init__(self, x, y):
self.x = x
self.y = y
def __call__(self):
return self.x + self.y
s = Sample(100, 200)
print(s(