如何有效且系统地重载Python类方法
假设你有一个Python类(版本>=2.6),里面有很多很多的方法(可能有几百个!)。现在,有人想要创建这个类的子类,但发现大部分基类的方法只需要做一些简单的“调整”。而且,调整这些方法的方式也不多,主要有几种:有的涉及输入的变化,有的涉及输出的变化,还有的两者都有。
更具体一点,我想要一个简单的解决方案,能够让我们在继承时,只需要提供基类和一个方法列表(这个列表里又是列表),来应用特定的调整,而不需要在每个重写的方法里都加上这些重复的代码。
谢谢,
eat
后续更新。
根据gabo10yf的回答,我想出了一个解决方案:
class B(object):
def f1(self, val):
print '1: ', val
def f2(self, val):
print '2: ', val
def decorator(f):
def g(self, *args, **kwargs):
print 'entering'
result= f(self, *args, **kwargs)
return g
class A(B):
pass
_overridden= ['f1', 'f2']
def override(cls):
for name in _overridden:
setattr(cls, name, decorator(getattr(cls, name).im_func))
override(A)
if __name__== '__main__':
b= B()
b.f1(1)
b.f2(2)
a= A()
a.f1(1)
a.f2(2)
这个方法看起来真的有效。不过感觉有点太简单了,肯定还有一些不太明了的问题吧?无论如何,感谢大家让我找到这个解决方案!
4 个回答
假设你有一个Python(版本>=2.6)的类,这个类里面有很多(上百个!)方法。
我会对这个类进行重构,因为这个类的设计有问题。
另外,你也可以通过对这个类的实例进行一种叫做猴子补丁的方式,轻松实现所需的结果。
我建议使用某种形式的面向切面编程。通过使用Logilab库,你可以很方便地在一个类的所有方法周围加上包装器。
希望这对你有帮助:
# the base class
class B(object):
def f1(self, val):
pass
def f2(self, val):
pass
这是一个装饰器的定义:
def decorator(cls, f):
def g(self, *args, **kwargs):
# 这里可以做一些事情
result = f(self, *args, **kwargs)
# 这里可以做更多事情
return g
接下来是一个类的定义:
class A(B):
_overridden = ['f1', 'f2']
@classmethod
def load(cls):
for name in cls._overridden:
setattr(name, decorator(getattr(name).im_func))
A.load()
可能需要做一些修改,以便处理类方法和静态方法。