Κατανόηση της μεθόδου super() της Python με τις μεθόδους __init__()

Προσπαθώ να καταλάβω τη χρήση της super(). Από ό,τι φαίνεται, και οι δύο κλάσεις-παιδιά μπορούν να δημιουργηθούν, μια χαρά.

Είμαι περίεργος να μάθω για την πραγματική διαφορά μεταξύ των ακόλουθων 2 παιδικών κλάσεων.

class Base(object):
    def __init__(self):
        print "Base created"

class ChildA(Base):
    def __init__(self):
        Base.__init__(self)

class ChildB(Base):
    def __init__(self):
        super(ChildB, self).__init__()

ChildA() 
ChildB()
Λύση

Η super() σας επιτρέπει να αποφεύγετε την ρητή αναφορά στη βασική κλάση, πράγμα που μπορεί να είναι καλό. Αλλά το κύριο πλεονέκτημα έρχεται με την πολλαπλή κληρονομικότητα, όπου μπορούν να συμβούν όλα τα είδη των διασκεδαστικών πραγμάτων. Δείτε τα standard docs on super αν δεν το έχετε κάνει ήδη.

Σημειώστε ότι η σύνταξη άλλαξε στην Python 3.0: μπορείτε απλά να πείτε super().__init__() αντί για super(ChildB, self).__init__() το οποίο IMO είναι αρκετά καλύτερο. Τα τυπικά έγγραφα παραπέμπουν επίσης σε έναν οδηγό χρήσης της super() που είναι αρκετά επεξηγηματικό.

Σχόλια (5)

Απλά μια προειδοποίηση... με την Python 2.7, και πιστεύω ότι από τότε που εισήχθη η super() στην έκδοση 2.2, μπορείτε να καλέσετε την super() μόνο αν ένας από τους γονείς κληρονομεί από μια κλάση που τελικά κληρονομεί το object (new-style classes).

Προσωπικά, όσον αφορά τον κώδικα της python 2.7, θα συνεχίσω να χρησιμοποιώ την BaseClassName.__init__(self, args) μέχρι να αποκτήσω πραγματικά το πλεονέκτημα της χρήσης της super().

Σχόλια (2)

Δεν υπάρχει, πραγματικά. Η super() κοιτάζει την επόμενη κλάση στην MRO (σειρά ανάλυσης μεθόδων, προσβάσιμη με την cls.__mro__) για να καλέσει τις μεθόδους. Η απλή κλήση της βασικής __init__ καλεί τη βασική __init__. Όπως συμβαίνει, η MRO έχει ακριβώς ένα στοιχείο-- τη βάση. Οπότε στην πραγματικότητα κάνετε ακριβώς το ίδιο πράγμα, αλλά με έναν πιο ωραίο τρόπο με την super() (ειδικά αν αργότερα ασχοληθείτε με την πολλαπλή κληρονομικότητα).

Σχόλια (6)