【问题标题】:How do I call a method of a subclass from a superclass method?如何从超类方法调用子类的方法?
【发布时间】:2012-06-18 12:34:27
【问题描述】:

假设我有这个类:

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 是代码的主类,所有小部件和主要功能都在其中。 这个类上还有一个按钮,绑定了“测试”功能。因此,当按下按钮时,整个事情都应该起作用。 MySubClass 文件是一个将数据导出到某个文件的辅助模块。 firstFunc 是该模块中处理所有数据的主要函数,而 secondFunc 只是构建文件的模板。所以我在 firstFunc 中调用这个 secondFunc 以便加载模板,然后将数据写入文件中。 我使这个 MySubClass 继承自 MyClass,以便它可以直接从 MyClass 访问数据库和其他变量。

所以我想我可以这样做。但我对这种实现并不真正有经验。另外,对不起我的英语不好。

【问题讨论】:

  • “这是一个愚蠢的例子,但正是我想要做的” 但是为什么要在超类方法中从子类调用方法呢?这毫无意义……
  • 为什么你想这样做?正如你所描述的,你真的不应该这样做。真的真的不应该。请描述您想要达到的目标。几乎可以肯定有一个正确的方法来实现它。
  • 我刚刚编辑了问题,以便我的目标变得更加清晰。谢谢。

标签: python class inheritance


【解决方案1】:

您不会从MyClass 的实例调用此方法,而是从MySubclass 的实例调用它。问题是你可能得到一个TypeError,因为你传递给firstFunc 的参数(self)是错误的类型(MyClass 而不是MySubClass)。解决方案是重组您的代码,这样就不会发生这种情况。至少,我认为这是问题所在(当我尝试编写代码时,我遇到了各种导入错误)。这是我尝试过的代码(我假设它说明了您所描述的问题):

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 中调用该函数。无论如何我都不能完成这项工作吗?
  • 我想不到。为什么需要在 MyClass 中调用该函数?您可以将 firstFunc 和 secondFunc 更改为常规函数——然后您可以将这些函数绑定为 MySubClass 上的常规方法...(我会更新)
  • 非常感谢@mgilson。我按照你说的方式重组了我的代码,现在它可以工作了。我确实知道这些函数现在没有被继承,它们是直接从子类调用的。但我承认我对这一切有点困惑,我将不得不对此进行更多研究。
【解决方案2】:

变化:

d = self.secondFunc(self, c)

收件人:

d = self.secondFunc(c)

【讨论】:

  • 仍然出现此错误:“AttributeError: 'MyClass' object has no attribute 'secondFunc'”
【解决方案3】:

当它是一个实例方法时,你试图调用firstFunc,就好像它是一个静态方法一样。可以使用classmethod装饰器来实现静态方法效果。

【讨论】:

  • 我会把 @classmethod 放在 secondFunc() 上,但它仍然会引发该错误。这是你的意思还是我做错了?
猜你喜欢
  • 2011-12-08
  • 2011-10-24
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
相关资源
最近更新 更多