2012-03-29 9 views
0

sagen, dass ich diesen Beispielcode habe ich mich für ein Python Lektion Schreiben Ich halte:Was ist falsch mit superclass.method (Objekt, Parms)?

class Enum(dict): 
    def __init__(self, *values): 
    values = {mnemo: num 
     for num, mnemo in enumerate(values)} 
    dict.__init__(self, values) # ← this 
    def __getattr__(self, name): 
    return self[name] 

Dies ist zumindest auf einem flachen Verfahren wie erwartet zu funktionieren scheint, aber was ich die meiste Zeit sehen auf der Literatur im Internet ist:

Ich denke, vor allem letzteres ist mehr TROCKEN, aber super() wird komplizierter zu erklären, sobald ich anfange, Mehrfachvererbung zu werfen. Ich möchte sicherstellen, dass es dort keine bösen Überraschungen gibt, auf die andere Leute stoßen werden.

+0

Wenn Sie Super einführen, tun Sie es richtig. Man kann es nicht gut gebrauchen, ohne das Konzept des MRO zu verstehen. Siehe [Pythons Super() als Super!] (Http://rhettinger.wordpress.com/2011/05/26/super-considered-super/). – delnan

+0

@ Delnan Ich habe tatsächlich erwogen, es überhaupt nicht einzuführen: P – badp

Antwort

4
  1. Ich sehe nicht, warum Sie im Allgemeinen vermeiden sollten, von eingebauten Typen abzuleiten. Es wurde als eine Verbesserung angesehen, dass die Ankunft von Klassen neuen Stils dies ermöglichte, und sogar vorher lieferte die Standardbibliothek die Klassen UserDict und UserList, von denen sie abstammen. Natürlich muss man in jedem konkreten Fall beurteilen, ob Vererbung oder Komposition das ist, was man braucht, aber so ist es immer in OOP - nichts Besonderes an eingebauten Typen hier.

  2. Ich würde super() in dem Beispiel nicht empfehlen. Es ist nur sinnvoll, wenn alle kooperierenden Methoden die gleiche oder zumindest kooperierende Signaturen haben. Für die einfache Vererbung und die "diamantfreie" Mehrfachvererbung ist das explizite Aufrufen von Basisklassenmethoden meiner Meinung nach in Ordnung. Wenn Sie die Dinge richtig in Mehrfachvererbung mit Diamanten erhalten möchten, werden Sie verwenden super() gezwungen, aber Sie haben Ihre Methoden sorgfältig zu entwerfen, sehen Raymond Hettinger's "Python's super() considered super!"

    Es ist im Allgemeinen sicher super() in Fällen zu verwenden, in denen alle beteiligten Methoden genau haben die gleiche Signatur, einschließlich Methoden wie __getattr__() und __setattr__().

  3. Ihre Beispielklasse ist eine eher fragwürdige Implementierung eines Enum Typs, aber aus keinem der Gründe, die Sie in Ihrem Beitrag erwähnt haben. Es vermischt zwei Namespaces: Den Namespace der Attribute dict und die Enumerationseinträge. Versuchen Sie Enum("clear", "update") um zu sehen, was ich meine. In diesem speziellen Fall wäre die follwing Implementierung viel besser:

    class Enum(object): 
        def __init__(self, *values): 
         vars(self).update({mnemo: num for num, mnemo in enumerate(values)}) 
    

    Dies fügt die Aufzählung Einträge als Attribute zu einer Standard-Instanz ohne dict abzuleiten. Jede benutzerdefinierte Klasseninstanz enthält ohnehin ein eigenes Wörterbuch, nämlich __dict__.

+1

Re: 1. Es gibt keine Garantie überschrieben overriden Methoden werden von eingebauten nicht überschriebenen Methoden aufgerufen. Wenn Sie beispielsweise von "dict" erben und "__getitem__" überschreiben, aber nicht "get", kann letzterer die Überschreibung für den ersten umgehen. – delnan

+0

@ Delnan: Guter Punkt. –