[GO] Was beim Nachahmen zu tun ist, wird in Python eingebettet

Einführung

Was ich beim Nachahmen mache, ist das Einbetten in Python oder eher die Delegierung als die Vererbung.

Die Geschichte, dass Vererbung schwierig ist

Einer der Gründe, warum Vererbung schmerzhaft ist, ist, dass Sie nicht wissen, welche Methode aufgerufen wurde.

Zum Beispiel für C mit der folgenden Vererbungsbeziehung

class A:
    def f(self):
        return "f"

    def g(self):
        return "g"


class B:
    def h(self):
        return "h"

    def i(self):
        return "i"


class C(A, B):
    def m(self):
        return (self.f(), self.i())

Es ist schwierig, das Verarbeitungsverhalten von "C # m ()" zu verstehen. Natürlich denke ich, dass ich normalerweise etwas genauer über den Namen bin, also denke ich nicht, dass es so schlimm sein sollte.

Auf der anderen Seite ist es immer noch besser, wenn es delegiert wird.

class C:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def m(self):
        return (self.a.f(), self.b.i())

Dies liegt daran, dass angegeben wird, welche Methode der intern gehaltenen Instanzvariablen aufgerufen wird.

Einbettung gehen

Hier ist die Einbettung von go. Dies kann auch als eine Funktion angesehen werden, die die Delegierung halbautomatisch ausführt.

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

type ReadWriter interface {
    Reader
    Writer
}

ReadeWriter verfügt über Reader- und Writer-Funktionen. Im Wesentlichen delegiert es nur an den Wert, den es in sich hat. Das obige Beispiel war ein Beispiel für eine Schnittstelle, aber das Gleiche gilt für struct.

type ReadWriter struct {
    *Reader  // *bufio.Reader
    *Writer  // *bufio.Writer
}

Wenn Sie so etwas wie "rw.Read ()" für eine Variable rw ausführen, die hier zu "var rw * ReadWriter" wird, wird so etwas wie "rw.Reader.Read ()" aufgerufen.

Nachahmung der Einbettung in Python

Geh zurück zu Python. Sie haben im ersten Beispiel erwähnt, dass Delegierung besser ist als Vererbung. Es wurde jedoch von der Delegation nicht vollständig gelöst. Möglicherweise möchten Sie die Methoden A und B direkt von C aus aufrufen. Wenn Sie etwas wie "c.a.f ()" direkt dort ausführen, wo Sie C verwenden, werden die Werte, die tatsächlich verwendet werden können, auf die C-Instanz festgelegt.

Aus diesem Grund möchten Sie, dass "c.a.f ()" intern aufgerufen wird, während Sie "c.f ()" aufrufen. Es ist jedoch schmerzhaft, die erforderlichen Methodenaufrufe jedes Mal explizit zu schreiben. Ich würde mich freuen, wenn Sie es automatisch tun könnten. Mit anderen Worten, es ist eine Nachahmung der Einbettung go.

Das Hauptthema ist von hier aus, aber wenn Sie die Einbettung von go with python imitieren möchten, mache ich persönlich Folgendes.

class C:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def m(self):
        return (self.a.f(), self.b.i())

    def __getattr__(self, name):
        return getattr(self.a, name)

Dies ändert automatisch "c.f" in "c.a.f". Dies ahmt die Einbettung von go nicht vollständig nach. Wenn ein nicht vorhandenes Attribut angegeben wird, wird alles an self.a delegiert. Sie können dies etwas expliziter oder restriktiver tun, indem Sie Metaprogrammierung usw. verwenden. Ich denke das ist genug für jetzt.

Wenn es mehrere Vererbungsquellen gibt

Im ursprünglichen Beispiel gab es mehrere Vererbungsquellen. Im vorherigen Beispiel können wir nur den Fall behandeln, in dem es nur eine Vererbungsquelle gibt. Schauen wir uns auch mehrere Fälle an. Der zu beachtende Punkt ist, wie man getattr verwendet. Sie können den Standardwert für das dritte Argument von getattr angeben. Versuchen Sie, anstelle von None einen speziellen Wert zurückzugeben. Dies liegt daran, dass selbst wenn Keine festgelegt ist, nach dem nächsten Suchziel gesucht wird (im Gegenteil, wenn Sie nach einem anderen Kandidaten suchen möchten, wenn Keine vorhanden ist, können Sie dies tun. Verstehen Sie das Verhalten. Ich empfehle es nicht, weil es schwierig sein wird).

missing = object()


class C:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def m(self):
        return (self.a.f(), self.b.i())

    def __getattr__(self, name):
        v = getattr(self.a, name, missing)
        if v is not missing:
            return v
        return getattr(self.b, name)

Jetzt ruft c.i () c.b.i () auf und c.f () ruft c.a.f () `auf.

Apropos

Übrigens habe ich im ursprünglichen Beispiel ein Beispiel geschrieben, in dem Werte, die mehrere A und B erben, im letzten Beispiel in mehreren Übertragungszielen unterstützt werden. Im tatsächlichen Code wird nicht empfohlen, eine solche implizite Übertragung an mehrere Übertragungsziele durchzuführen. Dies liegt daran, dass es schwierig wird, das Verhalten durch Betrachten des Putt zu erfassen. Daher ist es besser, das Übertragungsziel so weit wie möglich auf nur ein Ziel zu beschränken.

Recommended Posts

Was beim Nachahmen zu tun ist, wird in Python eingebettet
[Frage] Was passiert, wenn Sie% in Python verwenden?
Was ich in Python gelernt habe
Ich möchte am Ende etwas mit Python machen
Was tun, wenn in Python "SSL: CERTIFICATE_VERIFY_FAILED _ssl.c: 1056" angezeigt wird?
Was tun, wenn ModuleNotFoundError: In Python tritt kein Modul mit dem Namen 'XXX' auf
Was tun, wenn der Werttyp in Python nicht eindeutig ist?
Was soll ich verwenden, um Typvergleiche in Python durchzuführen?
Ich möchte Dunnetts Test in Python machen
[Python] Was ich getan habe, um Unit Test zu machen
Wenn ich matplotlib in Python versuche, heißt es'cairo.Context '.
Was ich beim Update von Python 2.6 auf 2.7 gemacht habe
Was soll ich mit DICOM von MPEG2 machen?
Was tun, um eine Google-Tabelle in Python zu erhalten?
[Python] Was tun, wenn bei send_keys in Headless Chrome ein Fehler auftritt?
Was tun, wenn eine Warnung zur Python-Integration in Neovims CheckHealth angezeigt wird?
Was ich getan habe, als ich mit Lambda Python im Zeitlimit steckte
Was tun, wenn [Errno 2] in Python keine solche Datei oder kein solches Verzeichnis angezeigt wird?
[Go 1.13] Was tun, wenn ein unerwartetes Verzeichnislayout angezeigt wird?
[openpyxl] Was tun, wenn IllegalCharacterError in pandas.DataFrame.to_excel angezeigt wird?
Was tun, wenn "Name xxx nicht importiert werden kann" [Python]
Wovon ich süchtig war, als ich Python Tornado benutzte
Was tun, wenn beim Importieren von matplotlib in Python (Mac) eine Fehlermeldung angezeigt wird?
Ich habe Python auf Japanisch geschrieben
Achtung bei os.mkdir in Python
Ich verstehe Python auf Japanisch!
Was tun, wenn `Argumente [0] .scrollIntoView ();` in Python-Selen fehlschlägt?
Was ich an der GUI in der WSL-Python-Umgebung hängen geblieben bin
Ich möchte so etwas wie Uniq in Python sortieren
Wovon ich süchtig war, als der Processing-Benutzer zu Python wechselte
Was tun, wenn in Django "Ungültiger HTTP_HOST-Header" angezeigt wird?
Was wurde gefragt, wenn Random Forest in der Praxis verwendet wurde?
Was tun, wenn aufgrund der Proxy-Einstellungen in Python Web Scraping keine Antwort erfolgt?
Was tun, wenn Ubuntu abstürzt?
[Python] Wie man PCA mit Python macht
Vorsichtsmaßnahmen bei der Verwendung von Pit mit Python
Was tun, wenn in Python minus Null angezeigt wird?
Verhalten beim Auflisten in Python heapq
Ich habe einen AttributeError erhalten, als ich die offene Methode in Python verspottet habe
Wovon ich süchtig war, als ich ALE in Vim für Python einführte
Was ich mit json.dumps in Pythons base64-Codierung süchtig gemacht habe
Ich habe Fizz Buzz in Python geschrieben
Was tun mit PYTHON Release?
Was tun, wenn beim Ausführen von Python eine Warnung zur unsicheren Plattform angezeigt wird?
Ich habe es mit Grumpy versucht (Python ausführen).
Ich wollte so etwas wie Elixirs Pipe in Python machen
Ich habe versucht, den Prozess mit Python zu studieren
Scikit-learn kann nicht in Python installiert werden
Schreiben Sie auf, was ich bei der Formatierung von Pos-Daten mit ipython verwendet habe
Bei Verwendung von @property in Python wird ein Attribut nicht festgelegt
Ich habe die Warteschlange in Python geschrieben
Was ich getan habe, als ich Python schneller machen wollte - Numba Edition -
Was tun, wenn "Ich kann die Site nicht sehen !!!!"
Was tun, wenn UnicodeDecodeError während read_csv in Pandas auftritt (pd.read_table ())
Welche Automatisierung sollte in der Programmiersprache RPA, VBA durchgeführt werden?
Ich habe Line Benachrichtigung in Python versucht
NameError: Der globale Name'dot_parser 'ist nicht definiert und was ist zu tun, wenn er in Python angezeigt wird?
Bei Verwendung regulärer Ausdrücke in Python