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

发布于 2024-10-12 15:04:40 字数 873 浏览 8 评论 0原文

假设您有一个包含大量(数百个!)方法的 Python (>=2.6) 类。现在有人想要子类化它,但意识到大多数基类方法只需要一些简单的“调整”。此外,只有少数几种不同的方法可以调整这些方法。有些涉及输入转换,有些涉及输出转换,有些两者都涉及。

更具体地说,我正在寻找一个(简单的)继承解决方案,我只需提供基类和方法列表(列表)来应用特定的转换,而不需要将此样板代码添加到每个重载方法中。

谢谢, 吃

跟进。
根据 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)

它似乎确实有效。不过感觉太简单了,想必其中还隐藏着一些隐晦的问题吧?无论如何,谢谢你们让我弄清楚了这一点!

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 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

篱下浅笙歌 2024-10-19 15:04:40

我希望这有帮助:


 # the base class
class B(object):
    def f1(self, val):
        pass
    def f2(self, val):
        pass

def 装饰器(cls,f): def g(self, *args, **kwargs): # 做事 结果 = f(self, *args, **kwargs) # 做更多事情 返回g

类A(B): _overridden = ['f1', 'f2'] @类方法 默认负载(cls): 对于 cls._overridden 中的名称: setattr(name, 装饰器(getattr(name).im_func))

A.load()

为了处理类和静态方法,可能需要进行一些更改。

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.

与他有关 2024-10-19 15:04:40

我建议使用某种形式的面向方面编程。使用 Logilab 库,可以轻松地对类的所有方法进行包装。

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.

很快妥协 2024-10-19 15:04:40

在继承之前我会考虑装饰器。

我还会考虑重构该类 - 数百种方法向我暗示了“上帝反模式”。

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.

月亮邮递员 2024-10-19 15:04:40

假设您有Python (>=2.6)
课堂上有很多(数百个!)
方法

我将重构该类,因为该类的设计已被破坏。

此外,您可以通过猴子修补所述类的实例轻松实现给定结果。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文