装饰父类方法

1 投票
3 回答
965 浏览
提问于 2025-04-11 09:16

我想创建一个子类,这个子类里有一个方法,这个方法在父类中是普通的方法,但在子类中却是一个“类方法”。

简单来说,我想实现以下功能:

class foo(Object):
    def meth1(self, val):
        self.value = val

class bar(foo):
    meth1 = classmethod(foo.meth1)

3 个回答

0

这个问题听起来有点奇怪:我不明白为什么有人会想要这样做。可能你对Python中的“类方法”(classmethod)有些误解,它和Java中的静态方法有点不同。

普通方法基本上就是一个函数,它的第一个参数通常叫“self”,代表类的一个实例,并且通过“.”来调用。

类方法基本上也是一个函数,它的第一个参数通常叫“cls”,代表类本身,可以通过“.”来调用,也可以通过“类名.”来调用。

考虑到这一点,结合你上面展示的代码,如果有人创建了一个bar的实例并调用meth1,你觉得会发生什么呢?

bar1 = bar()
bar1.meth1("xyz")

当调用meth1的代码时,会传入两个参数“self”和“val”。我猜你希望“val”传入“xyz”,但你觉得“self”会传入什么呢?应该是bar1这个实例(在这种情况下,不需要重写)吗?还是应该是类bar(那这样代码会做什么呢)?

3

你想要达到什么目的呢?如果我在实际的Python代码中看到这样的写法,我可能会想要找那个写代码的人好好说说。

4

我也不太确定你想要的具体行为是什么,但假设你是想让 bar.meth1(42) 和 foo.meth1 作为 bar 的类方法(这里的 "self" 是指类本身)等价,那么你可以这样做:

def convert_to_classmethod(method):
    return classmethod(method.im_func)

class bar(foo):
    meth1 = convert_to_classmethod(foo.meth1)

使用 classmethod(foo.meth1) 的问题在于,foo.meth1 已经被转换成了一个方法,这样它的第一个参数有了特殊的含义。你需要把这个转换撤销,直接查看它的底层函数对象,重新理解 "self" 的意思。

我还想提醒你,这样做其实挺奇怪的,可能会让阅读你代码的人感到困惑。你可能更应该考虑其他解决问题的方法。

撰写回答