Calling an overridden method, superclass an calls overridden method

后端 未结 4 1834
情深已故
情深已故 2021-01-08 00:39

This code throws an exception, AttributeError, \"wtf!\", because A.foo() is calling B.foo1(), shouldn\'t it call A.foo1()? Ho

相关标签:
4条回答
  • 2021-01-08 00:52

    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.)

    0 讨论(0)
  • 2021-01-08 00:56

    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.

    0 讨论(0)
  • 2021-01-08 00:58

    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)
    
    0 讨论(0)
  • 2021-01-08 01:09

    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()
    
    0 讨论(0)
提交回复
热议问题