调用重写的方法,超类调用重写的方法

发布于 2024-12-11 11:38:49 字数 541 浏览 0 评论 0原文

此代码抛出异常,AttributeError,“wtf!”,因为 A.foo() 正在调用 B.foo1(),应该'它调用A.foo1()吗?如何强制它调用 A.foo1() (并且 A.foo() 内的任何方法调用都应该调用 A.*

class A(object):
    def foo(self):
        print self.foo1()

    def foo1(self):
        return "foo"

class B(A):
    def foo1(self):
        raise AttributeError, "wtf!"

    def foo(self):
        raise AttributeError, "wtf!"

    def foo2(self):
        super(B, self).foo()

myB = B()
myB.foo2()

This code throws an exception, AttributeError, "wtf!", because A.foo() is calling B.foo1(), shouldn't it call A.foo1()? How can I force it to call A.foo1() (and any method call inside A.foo() should call A.*)

class A(object):
    def foo(self):
        print self.foo1()

    def foo1(self):
        return "foo"

class B(A):
    def foo1(self):
        raise AttributeError, "wtf!"

    def foo(self):
        raise AttributeError, "wtf!"

    def foo2(self):
        super(B, self).foo()

myB = B()
myB.foo2()

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

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

发布评论

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

评论(4

山川志 2024-12-18 11:38:49

在类 A 中,您需要调用 A 方法并手动传入 self 方法,而不是调用 self 方法。

这不是正常的做事方式——您应该有一个真正充分的理由这样做。

class A(object):
    def foo(self):
        print A.foo1(self)

    def foo1(self):
        return "foo"

class B(A):
    def foo1(self):
        raise AttributeError, "wtf!"

    def foo(self):
        raise AttributeError, "wtf!"

    def foo2(self):
        super(B, self).foo()

myB = B()
myB.foo2()

In class A instead of calling self methods you need to call A methods and pass in self manually.

This is not the normal way of doing things -- you should have a really good reason for doing it like this.

class A(object):
    def foo(self):
        print A.foo1(self)

    def foo1(self):
        return "foo"

class B(A):
    def foo1(self):
        raise AttributeError, "wtf!"

    def foo(self):
        raise AttributeError, "wtf!"

    def foo2(self):
        super(B, self).foo()

myB = B()
myB.foo2()
舂唻埖巳落 2024-12-18 11:38:49

在代码中:

def foo2(self):
    super(B, self).foo()

self 是 B 的实例。

当 B 的实例调用从 A 派生的方法时,它将开始在 B 的命名空间中查找,并且仅当未找到该方法时(例如,未被 B 覆盖)使用 A 的实现,但总是使用 self 引用 B。在任何时候 self 都不是 A 的实例。

In the code:

def foo2(self):
    super(B, self).foo()

self is an instance of B.

When a method derived from A is called by an instance of B it will start looking in the namespace from B, and only if the method is not found (e.g. is not overridden by B) the implementation from A is used, but always with self referring to B. At no point self is an instance of A.

情域 2024-12-18 11:38:49

它正在按预期工作,就像世界上 100% 的编程语言一样。子类重写父类的所有方法。

但是,如果您真的想调用 A.foo1(),您也许可以这样做(我不能保证)。无论如何,您都不能这样做,因为这违反了良好编程的所有原则。

 class A(object):

    def foo(self):
        A.foo1(self)

It is working as intended, as 100% of world programming languages work. Subclass overrides ALL methods of parent class.

However if you really really want to call the A.foo1() you might be able to do it like this (I cannot guarantee). And in any case you must not do this as this is against all principles of good programming.

 class A(object):

    def foo(self):
        A.foo1(self)
捶死心动 2024-12-18 11:38:49

可以看出Python在这里做了什么,但是重写的方式有点极端。以类 A 定义 100 个属性而类 B 继承这些属性并添加 1 个属性的情况为例。我们希望能够让 B 的 __init__() 调用 A 的 __init__() 并让 B 的代码仅定义其单个属性。类似地,如果我们在A中定义一个reset()方法将所有属性设置为零,那么B的相应reset()方法应该能够只调用A的reset()方法,然后将单个B属性清零必须复制 A 的所有代码。 Python 正在使面向对象编程的主要优点变得困难。也就是代码的重用。这里最好的选择是避免覆盖我们真正想要重用的方法。如果您想了解 Python 的复杂性,请尝试以下代码:(

class X(object):
    def __init__ ( self ):
        print "X"
        self.x = 'x'
        self.reset()
        print "back to X"
    def reset ( self ):
        print "reset X"
        self.xx = 'xx'

class Y(X):
    def __init__ ( self ):
        print "Y"
        super(Y,self).__init__()
        self.y = 'y'
        self.reset()
        print "back to Y"
    def reset ( self ):
        print "reset Y"
        super(Y,self).reset()
        print "back to reset Y"
        self.yy = 'yy'

aY = Y()

要使其正常工作,请删除 Y 类的 __init__() 中的 self.reset() 调用。)

One can see what Python is doing here, but the manner of overriding is a bit extreme. Take the case when class A defines 100 attributes and class B inherits these and add 1 more attribute. We want to be able to have the __init__() for B call the __init__() for A and let B's code define only its single attribute. Similarly, if we define a reset() method in A to set all attributes to zero, then the corresponding reset() method for B should be able just to call the reset() method for A and then zero out the single B attribute instead of having to duplicate all of A's code. Python is making difficult what is supposed to be a major advantage of object-oriented programming; that is, the reuse of code. The best option here is avoid overriding of methods that we really want to reuse. If you want to get a sense of the complications with Python here, try this code:

class X(object):
    def __init__ ( self ):
        print "X"
        self.x = 'x'
        self.reset()
        print "back to X"
    def reset ( self ):
        print "reset X"
        self.xx = 'xx'

class Y(X):
    def __init__ ( self ):
        print "Y"
        super(Y,self).__init__()
        self.y = 'y'
        self.reset()
        print "back to Y"
    def reset ( self ):
        print "reset Y"
        super(Y,self).reset()
        print "back to reset Y"
        self.yy = 'yy'

aY = Y()

(To make this work properly, remove the self.reset() call in __init__() for class Y.)

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