如何有效且系统地重载Python类方法

1 投票
4 回答
1075 浏览
提问于 2025-04-16 10:08

假设你有一个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 个回答

0

假设你有一个Python(版本>=2.6)的类,这个类里面有很多(上百个!)方法。

我会对这个类进行重构,因为这个类的设计有问题。

另外,你也可以通过对这个类的实例进行一种叫做猴子补丁的方式,轻松实现所需的结果。

2

我建议使用某种形式的面向切面编程。通过使用Logilab库,你可以很方便地在一个类的所有方法周围加上包装器。

2

希望这对你有帮助:


 # 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()

可能需要做一些修改,以便处理类方法和静态方法。

撰写回答