How do overridden method calls from base-class methods work?

后端 未结 5 1326
我寻月下人不归
我寻月下人不归 2021-02-18 13:01

According to the docs on inheritance:

Derived classes may override methods of their base classes. Because methods have no special privileges when calling

5条回答
  •  面向向阳花
    2021-02-18 13:49

    How does it work?

    When an attribute look-up is performed on an instance of the class, the class dictionary and the dictionaries of its base classes are searched in a certain order (see: Method Resolution Order) for the appropriate method. What is found first is going to get called.

    Using the following Spam example:

    class Spam:
        def produce_spam(self):
            print("spam")
        def get_spam(self):
            self.produce_spam()
    
    class SuperSpam(Spam):
        def produce_spam(self):
            print("super spam")
    

    Spam defines the functions produce_spam and get_spam. These live in its Spam.__dict__ (class namespace). The sub-class SuperSpam, by means of inheritance, has access to both these methods. SuperSpam.produce_spam doesn't replace Spam.produce_spam, it is simply found first when the look-up for the name 'produce_spam' is made on one of its instances.

    Essentially, the result of inheritance is that the dictionaries of any base classes are also going to get searched if, after an attribute look-up on the sub-class is made, the attribute isn't found in the sub-class's dictionary.

    When the function get_spam is first invoked with:

    s = SuperSpam()
    s.get_spam()
    

    the sequence of events roughly goes like this:

    • Look into SuperSpams __dict__ for get_spam.
    • Since it isn't found in SuperSpams __dict__ look into the dictionaries of it's base classes (mro chain).
    • Spam is next in the mro chain, so get_spam is found in Spam's dictionary.

    Now, when produce_spam is looked up in the body of get_spam with self.produce_spam, the sequence is much shorter:

    • Look into SuperSpam's (self) __dict__ for produce_spam.
    • Find it, get it and call it.

    produce_spam is found in the __dict__ first so that gets fetched.

提交回复
热议问题