如何从超类方法中调用子类的方法?

4

假设我有这个类:

class MyClass(object):
    def uiFunc(self, MainWindow):
        self.attr1 = "foo"
        self.attr2 = "bar"
    def test():
        from subclassfile import MySubClass
        MySubClass.firstFunc(self, 2, 2)

    test()

而这个子类在另一个文件中:

from classfile import MyClass

class MySubclass(MyClass):
    def firstFunc(self, a, b):
        c = a + b
        d = self.secondFunc(self, c)
        return d

    def secondFunc(self, c):
        d = c / 2
        return d

这只是一个愚蠢的例子,但确切地代表了我想做的事情。 我想从子类中的第一个函数调用第二个函数。 但当我这样做时,它会返回一个错误,说MyClass没有这样的函数。 所以我想当我调用它时,在函数名前面不应该使用self。但是当我不这样做时,它也会引发错误。
因此,我的问题是: 如何在子类的第一个函数中访问这个第二个函数?
编辑:
谢谢大家的帮助。我将更好地解释我正在尝试做什么,虽然我猜测我的实现在代码中确实很糟糕。 MyClass是代码的主类,其中包含所有小部件和主要功能。 还有一个按钮在这个类上,与“test”函数绑定。因此,当按下按钮时,整个过程应该正常工作。 MySubClass文件是一个辅助模块,将数据导出到某个文件中。 firstFunc是处理所有数据的主要函数,而secondFunc只是构建文件的模板。因此,我在第一个函数中调用这个secondFunc,以便加载模板,然后将数据写入文件。 我使这个MySubClass从MyClass继承,以便它可以直接从MyClass访问数据库和其他变量。
所以我想我可以用另一种方式做到这一点。但我对这种实现方式并不是很有经验。另外,对于我的糟糕英语,我感到抱歉。

2
“这只是一个愚蠢的例子,但恰好代表了我想做的事情。”但是,你为什么要在超类方法中调用子类中的方法呢?这毫无意义...” - brandizzi
你为什么想要这样做?根据你的描述,你真的不应该这样做。真的真的不应该。请描述你想要实现什么目标。几乎肯定有一种正确的方法来实现它。 - Chris Morgan
我刚刚编辑了问题,使我的目标更加清晰。谢谢。 - jonathan.hepp
3个回答

2

更改:

d = self.secondFunc(self, c)

致:

d = self.secondFunc(c)

仍然存在这个错误:"AttributeError:'MyClass'对象没有属性'secondFunc'"。 - jonathan.hepp

2
你不应该从MyClass的实例调用这个方法,而是应该从MySubclass的实例中调用它。问题在于你可能会收到TypeError错误,因为你传递给firstFunc方法的参数(self)类型错误,传递的应该是MySubClass而不是MyClass。解决方法是重新组织你的代码,以避免出现这种情况。至少我认为这可能是问题所在(当我尝试运行你的代码时,我遇到了各种导入错误)。下面是我尝试的代码(我认为它说明了你描述的问题):
class MyClass(object):
    def uiFunc(self, MainWindow):
        self.attr1 = "foo"
        self.attr2 = "bar"
    def test(self):
        return MySubClass.firstFunc(self, 2, 2)

class MySubClass(MyClass):
    def firstFunc(self, a, b):
        c = a + b
        d = self.secondFunc(c) #removed self from parameter list
        return d

    def secondFunc(self, c):
        d = c / 2
        return d


a=MyClass()
b=MySubClass()
print (b.test())  #this works because b is the right type to pass to first/second func
a.test()   #This doesn't work because a is the wrong type.

请注意,将test作为MyClass的方法并不真正有意义,因为您无法从那里使用它。您最好将test移到MySubClass上。
此外,正如其他人指出的那样,self.secondfunc(self,c)也非常奇怪。 这基本上相当于MySubClass.secondfunc(self,self,c),其中参数数量错误,因为您传递了self两次。
以下是可以运行的代码:
class MyClass(object):
    def uiFunc(self, MainWindow):
        self.attr1 = "foo"
        self.attr2 = "bar"
    def test(self):
        return firstFunc(self, 2, 2)


def firstFunc(self, a, b):
    c = a + b
    d = secondFunc(self,c) #self from in front of function, now in parameter list
    return d

def secondFunc(self, c):
    d = c / 2
    return d

class MySubClass(MyClass):
    firstFunc=firstFunc
    secondFunc=secondFunc


a=MyClass()
b=MySubClass()
print (b.test())
print (a.test())

但是我强烈建议重构您的代码。


谢谢你的帮助。但是,我真的需要在MyClass内部调用那个函数。有没有什么方法可以让这个工作? - jonathan.hepp
我想不出其他的方法。为什么你需要在MyClass内调用那个函数?你可以将firstFunc和secondFunc更改为常规函数--然后你可以将这些函数绑定为MySubClass的常规方法...(我会更新) - mgilson
非常感谢@mgilson。我按照您所说的重新组织了代码,现在它可以工作了。我确实明白函数现在不再被继承,而是直接从子类中调用。但我承认我对这一切有点困惑,我需要更多地学习。 - jonathan.hepp

1

您试图将firstFunc作为静态方法调用,但它是实例方法。您可以使用classmethod装饰器来实现静态方法的效果。


我已经在secondFunc()上使用了@classmethod,但仍然出现错误。这是你想要的吗?还是我做错了什么? - jonathan.hepp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接