开发者

How to overload effectively and systematically Python class methods

开发者 https://www.devze.com 2023-02-05 17:51 出处:网络
Assume that you have a Python (>=2.6) class with plenty (hundreds!) of methods. Now someone wants to subclass that but realized that most of the base class methods needs only some simple \'tuning\'. A

Assume that you have a Python (>=2.6) class with plenty (hundreds!) of methods. Now someone wants to subclass that but realized that most of the base class methods needs only some simple 'tuning'. Also there are only handful of different ways to tune those methods. Some involving input transformations, some output transformations, some both.

To be more specific I'm looking for a (simple) solution for the inheritance where I just could provide the 开发者_JS百科base class and a list (of lists) of methods to apply the specific transformations, without adding this boilerplate code to each overloaded method.

Thanks, eat

Follow up.

Based on gabo10yf answer, I came up a solution as:

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)

It really seems to work. However it feels almost too simple, it surely must still contain some murky issues? Anyway thanks to you all letting me figure out this!


I hope this helps:


 # 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): # do stuff result = f(self, *args, **kwargs) # do more stuff 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()

One may have to do some changes in order to handle class and static methods.


I suggest to use some form of Aspected-Oriented Programming. With the Logilab library, it is easy to put wrappers around all methods of a class.


I would consider decorators before I'd go for inheritance.

I'd also consider refactoring that class - hundreds of methods suggests "god anti-pattern" to me.


Assume that you have a Python (>=2.6) class with plenty (hundreds!) of methods

I will then refactor the class, because the class design is broken.

Also, you can easily achieve the given result by monkey patching an instance of said class.

0

精彩评论

暂无评论...
验证码 换一张
取 消