Metaklassen: Warum wird die Methode nicht von der Basisklasse geerbt?

maln0ir

Ich versuche, die schwarze Magie der Metaklasse in Python zu verstehen . AFAIK, Metaklassen können zum Beispiel verwendet werden, um sicherzustellen, dass einige Methoden in abgeleiteten Klassen implementiert sind, aber ich habe ein Problem mit Enkelkindern . Es scheint, dass ich alle erforderlichen abgeleiteten Methoden explizit implementieren muss, auch wenn es keinen Grund (?) Gibt, dies zu tun.

Schau dir das an:

~ $ ipython
Python 3.6.5 (default, Apr 14 2018, 13:17:30) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: class Meta(type):
   ...:     def __new__(cls, name, bases, body):
   ...:         if 'some_method' not in body:
   ...:             raise AttributeError('some_method should be implemented')
   ...:         return super().__new__(cls, name, bases, body)
   ...: 
   ...: class Base(metaclass=Meta):
   ...:     def some_method(self):
   ...:         print('Yay')
   ...: 
   ...: class Derived(Base):
   ...:     pass
   ...: 
   ...: 
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1-51c072cc7909> in <module>()
      9         print('Yay')
     10 
---> 11 class Derived(Base):
     12     pass

<ipython-input-1-51c072cc7909> in __new__(cls, name, bases, body)
      2     def __new__(cls, name, bases, body):
      3         if 'some_method' not in body:
----> 4             raise AttributeError('some_method should be implemented')
      5         return super().__new__(cls, name, bases, body)
      6 

AttributeError: some_method should be implemented

Soweit ich weiß, sollte dies nicht passieren, da some_methodes aus der BaseKlasse wie hier abgeleitet werden sollte:

In [3]: class Base:
   ...:     def some_method(self):
   ...:         print('Yay')
   ...: 
   ...: class Derived(Base):
   ...:     pass
   ...: 
   ...: 

In [4]: Derived().some_method()
Yay

Dies wird erwartet? Wenn ja, könnten Sie einen Hinweis geben Sie mir wie beheben dieses Verhalten, so würde ich nicht neu zu implementieren Methoden benötigen?

abarnert

Sie scheinen zu versuchen, das Rad, das das abcModul und seinen @abstractmethodDekorateur ist, neu zu erfinden . Ich bin mir nicht sicher, warum Sie das tun möchten, aber wenn Sie dies tun, sollten Sie sich die Quelle ansehen (die aus den Dokumenten verlinkt ist).

Ihre Lösung überprüft, ob der erforderliche Name im Hauptteil der Klasse implementiert ist. Das gilt nicht für geerbte Methoden, aber Sie scheinen das zu wissen, also werde ich es nicht erklären. Was Sie wissen möchten, ist: Was können Sie stattdessen tun? Sie müssen explizit nach geerbten Methoden suchen.

Die Art und Weise abcist ziemlich einfach: Bevor überprüft wird, ob alle abstrakten Methoden implementiert sind, wird getattrjede aufgerufen base. (Der beste Weg, um zu simulieren, was getattrin der Klasse passieren wird getattr, ist schließlich anzurufen .) Alles, was dort gefunden wird, muss nicht im Körper erscheinen.

Ihr Anwendungsfall - mit einer statischen einzelnen erforderlichen Methode anstelle eines dynamischen Satzes von Methoden, die aus der Ausgabe eines Dekorateurs gewonnen werden müssen - ist noch einfacher:

if (not any(hasattr(base, 'some_method') for base in bases)
    and 'some_method' not in body):

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

Identifizieren Sie die Basisklasse, von der eine Eigenschaft geerbt wird

Warum wird der folgende Fehler angezeigt: Enzyme Internal Error: Der konfigurierte Enzymadapter hat nicht von der EnzymeAdapter-Basisklasse geerbt

Warum funktioniert diese SFINAE nicht mit enable_if, wenn ein bedingter Zweig von der Basisklasse geerbt wird?

Die im Ersteller aufgerufene Methode wird von der Basisklasse aufgerufen, nicht jedoch von der abgeleiteten Klasse

Annotation wird nicht von der Schnittstellenmethode geerbt

Warum wird das JsonConverter-Attribut nicht von der Schnittstelle geerbt?

Warum wird mein Array von einer Methode zurückgegeben, die nicht auf der Konsole gedruckt wird?

Zwei Methoden, die von einer Methode in der Klasse geerbt wurden, unterscheiden sich in Instanzen, nicht wahr?

Warum wird die Implementierung der virtuellen Methode in der Mock-Klasse von GMock nicht erkannt?

Warum kann ich die Methode von QIODevice nicht erneut implementieren, wenn die Basisklasse QFile ist?

Warum wird mein Razor 'RenderSection' nicht von einer Enkelansicht geerbt?

Warum wird fstream in c ++ nicht von ifstream und ofstream geerbt?

Der in Abstract Class implementierte Action-Listener wird nicht von den Klassen geerbt, die ihn erweitern

Warum wird die Rückruffunktion der Methode .always von $ .ajax () nicht ausgeführt?

Warum wird die Aufgabe nicht abgebrochen, wenn ich die Cancelation-Methode von CancellationTokenSource in der asynchronen Methode aufrufe?

Hinzufügen von Methoden in einer Klasse, die von der abstrakten Basisklasse geerbt wurde?

Werden in C # die "using" -Anweisungen der Basisklasse von der untergeordneten Klasse geerbt?

Der Fehler "__init__ Methode von Basisklasse wird nicht aufgerufen" für eine abstrakte Klasse

Warum benutzerdefinierte Typattribute, die nicht von Generika geerbt werden?

Die Verwendung von @Retryable in Methoden, die in der Basisklasse von Spring Bean definiert sind, wird nicht wiederholt

Zugriffsmitglied einer nicht virtuellen Basisklasse, die von zwei verschiedenen Klassen geerbt wurde

Wie kann festgestellt werden, ob eine Eigenschaft nicht von der Basisklasse geerbt wurde?

Methode, die außerhalb der Klassenverzögerung deklariert wurde, konnte nicht von der untergeordneten Klasse in Javascript geerbt werden

Wie lösche ich eine reine virtuelle Funktion, die von der Basisklasse geerbt wurde?

Gibt verschachtelte Klasse zurück, die von der Basisklasse geerbt wurde

Warum wird die init-Methode von Decodable bei Verwendung der JSONDecoder.decode-Methode nicht aufgerufen?

Warum wird die Objekteigenschaft in der updateObject () -Methode in Java nicht aktualisiert?

Warum wird die Methode "gets" in der Autovervollständigung nicht angezeigt?

Warum wird die Methode __get__ der Metaklasse nicht aufgerufen?

TOP Liste

  1. 1

    So legen Sie mit dem Interface Builder unterschiedliche führende Speicherplätze für unterschiedliche Geräte fest

  2. 2

    Fügen Sie eine weitere Schaltfläche zu gwt Suggest Box hinzu

  3. 3

    Wie konvertiere ich einen Vektor von Bytes (u8) in eine Zeichenfolge?

  4. 4

    Wie kann ich in SCSS mehrere Klassen zu einer einzigen kombinieren?

  5. 5

    Wie konvertiert man einen Datenrahmen im langen Format in eine Liste mit einem geeigneten Format?

  6. 6

    Speichern Sie ein MPAndroidChart-Diagramm in einem Bild, ohne es in einer Aktivität anzuzeigen

  7. 7

    Gruppieren Sie Datenrahmenspalten nach ihrem Datum (die Spaltentitel enthalten) und fassen Sie die Instanzen von Einsen und Nullen in R . zusammen

  8. 8

    Tomcat - Leiten Sie den alten Kontextstamm zum neuen Kontextstamm um

  9. 9

    Eclipse Oxygen - Projekte verschwinden

  10. 10

    Wie wählt man Unterschiede mit drei Tabellen aus?

  11. 11

    Tic Tac Toe-Spiel im React-Reset-Button funktioniert nicht

  12. 12

    So berechnen Sie die Verfügbarkeit von Anwendungen (SLA)

  13. 13

    ElasticSearch BulkShardRequest ist aufgrund von org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor fehlgeschlagen

  14. 14

    Wie kann ich den Kaskadenmodus global einstellen?

  15. 15

    Python: Spalten mit demselben Namen zusammenführen, wobei der Mindestwert beibehalten wird

  16. 16

    So erhalten Sie eine gleichmäßige Höhe für alle Eingabefelder

  17. 17

    Wie erstelle ich einen neuen übergeordneten Knoten außerhalb der .ref (/ path) in der Firebase-Echtzeitdatenbank mithilfe von Cloud-Funktionen (Typescript)?

  18. 18

    Was ist schneller: SUM über NULL oder über 0?

  19. 19

    Wie kann ich eine verschachtelte Schleife mit lapply in R ersetzen?

  20. 20

    Kann ich ein Tkinter-Canvas erstellen, das mehrere Zeilen in einem Text-Widget umfasst?

  21. 21

    Ärgerliches Problem mit yaml, das ich nicht lösen kann

heißlabel

Archiv