Klassenvererbungspraxis in Python, wie in sklearn zu sehen

Einführung

Wie schreibe ich Klassenvererbung in Python? Ich werde eine praktische Ausgabe darüber schreiben. Es gibt keine Basisausgabe.

Wann ist es wichtig

Dies scheint beim Erstellen von Software und umfangreichen Bibliotheken hilfreich zu sein. Wenn Sie eine Methode schreiben, die in mehreren Klassen in der abstrakten Klasse oder in der übergeordneten Klasse, die als Vorlage dient, auf dieselbe Weise definiert ist, müssen Sie sie nicht in der untergeordneten Klasse definieren.

Nehmen wir dieses Mal das "TransformerMixin" von scikit-learn, das jeder liebt, als Beispiel. TransformerMixin ist eine Klasse, die überall beim Scikit-Lernen verwendet wird. In scikit-learn werden "fit" und "transform" häufig für die Vorverarbeitung usw. verwendet, und "fit_transform", das sie zusammen ausführt, wird in "Transformer Mixin" implementiert.

Dieser Mechanismus ist ein sehr einfaches Beispiel dafür, dass "fit_transform" nur durch Erben verwendet werden kann.

Als Referenz implementiert Python normalerweise eine abstrakte Klasse, die abc.ABCMeta erbt. Es gibt ein Paket namens abc, das in Python immer verfügbar ist und zum Definieren abstrakter Klassen verwendet wird. Siehe auch die Referenzen am Ende dieses Artikels.

abc — Abstract Base Classes

Was ich versucht habe

Ich habe die folgenden zwei Punkte ausprobiert. Ich werde schreiben.

  1. Lesen des Quellcodes
  2. Verschob den Beispielcode

Lesen des Quellcodes

Lesen wir zuerst den folgenden Code. Es stammt aus der Github-Seite von scikit-learn. scikit-learn TransformerMixin

base.py


...
class TransformerMixin:
    def fit_transform(self, X, y=None, **fit_params):
        ...
        if y is None:
        ...
            return self.fit(X, **fit_params).transform(X)
        else:
        ...
            return self.fit(X, y, **fit_params).transform(X)
...

Beim Definieren einer abstrakten Klasse in Python wird häufig eine Klasse namens "abc.ABCMeta" verwendet. Im obigen Beispiel wird jedoch nur die Methode ohne Verwendung von "abc.ABCMeta" definiert.

In der abstrakten Klasse mit abc.ABCMeta und @ abc.abstractmethod können Sie eine Klasse erstellen, die die Implementierung am geerbten Ziel erzwingt. Auf der anderen Seite möchten wir mit TransformerMixin oben allen Vererbungszielen nur gemeinsame Methoden zur Verfügung stellen. In diesem Fall müssen Sie nicht "abc" verwenden.

Beispielcode verschoben

Ich werde versuchen zu schreiben. Wenn Sie eine abstrakte Klasse verwenden, die "abc" verwendet, funktioniert dies wie folgt. Darüber hinaus machen Sie sich bitte keine Sorgen, da der Funktionsname usw. Abekobe ist ...

$ cat sampleAbsclass.py
from abc import ABCMeta, abstractmethod
class DensityMixin(metaclass=ABCMeta):
    @abstractmethod
    def score(self, X, y=None):
        pass

class OneClassSvm(DensityMixin):
    def __init__(self):
        print('echo echo', 'hello hello')
    # def score(self, X, y=None):
    #     print(*X.shape)

def main():
    ocsvm = OneClassSvm()
    from numpy.random import randn
    X=randn(100, 10)
    ocsvm.score(X)
    return 0

if __name__=='__main__':
    main()
$ python sampleAbsclass.py
Traceback (most recent call last):
  File "sampleAbsclass.py", line 21, in <module>
    main()
  File "sampleAbsclass.py", line 14, in main
    ocsvm = OneClassSvm()
TypeError: Can't instantiate abstract class OneClassSvm with abstract methods score

Es gibt eine Methode "score" mit einem "@ abstractmethod" -Dekorator im "DensityMixin" der abstrakten Klasse, die jedoch nicht im geerbten "OneClassSvm" ** Keshikaran implementiert ist! Die Fehlermeldung lautet **.

Wenn Sie die Score-Funktion von OneClassSvm auskommentieren, funktioniert sie wie folgt.

$ python sampleAbsclass.py
echo echo hello hello
100 10

Andere: Vorsichtsmaßnahmen bei der Verwendung von abc.ABCMeta

Eine weitere Einschränkung, die auftritt, wenn Sie "abc.ABCMeta" stark nutzen, besteht darin, dass Klasse A mehrere abstrakte Klassen erbt. "Wenn auch nur eine Klasse A eine abstrakte Klasse hat, die" abc.ABCMeta "erbt, müssen die anderen geerbten Klassen auch" abc.ABCMeta "erben." Es gibt einen Punkt. Wenn Sie dies unterbrechen, wird die folgende Fehlermeldung angezeigt.

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

Dies geschieht auch in anderen Sprachen, daher halte ich es für zweckmäßig, dies zu tun. Sie sollten die Theorie der Programmiersprache richtig lernen ...

Andere 2 Beispiel mit abc.ABCMeta

Es gibt eine Implementierung von scikit-learn, die abc.ABCMeta verwendet. Schauen wir uns also auch dort um. Das Folgende wird aus _PLS --scikit-learn zitiert. Sie können sehen, dass "@ abstractmethod" nur zur "__init __" -Methode hinzugefügt wird.

pls_.py


from abc import ABCMeta, abstractmethod
...
class _PLS(BaseEstimator, TransformerMixin, RegressorMixin, MultiOutputMixin,
           metaclass=ABCMeta):
...
    @abstractmethod
    def __init__(self, n_components=2, scale=True, deflation_mode="regression",
                 mode="A", algorithm="nipals", norm_y_weights=False,
                 max_iter=500, tol=1e-06, copy=True):
...
    def fit(self, X, Y):
...
    def transform(self, X, Y=None, copy=True):
...
    def predict(self, X, copy=True):
...
    def fit_transform(self, X, y=None):
...
    def _more_tags(self):
        return {'poor_score': True}

Andere Klassen erben diese _PLS-Klasse, ABCMeta wird jedoch erst zu diesem Zeitpunkt veröffentlicht. Die _PLS-Klasse selbst erbt nur Mixin und hat ab dem ersten Beispiel keine Vererbung der ABCMeta-Klasse.

Was also die Verwendung von abc.ABCMeta betrifft, ** wird eine Methode, die in mehreren Klassen implementiert werden muss, in die abstrakte Klasse geerbt **.

(Es ist ein Rätsel, fit_transform in _PLS neu zu definieren, obwohl es TransformerMixin erbt.)

Fazit

In diesem Artikel haben wir ausgehend vom Implementierungsbeispiel von TransformerMixin von scikit-learn kurz zusammengefasst, wie eine Klasse zum Organisieren gemeinsamer Teile erstellt wird. Es ist üblich, die Klasse "abc.ABCMeta" zu erben, um sie zu einer abstrakten Klasse zu machen. Wenn Sie jedoch nur eine oder zwei Methoden haben möchten, die mehreren Klassen gemeinsam sind, verwenden Sie "abc.ABCMeta" Ich habe bestätigt, dass dies unwahrscheinlich erscheint. Es ist albern, dieselbe Implementierung immer wieder zu wiederholen, also nutzen Sie die Klassenvererbung.

Verweise

Die Verwendung von abc.ABCMeta wird im folgenden Artikel vorgestellt.

Recommended Posts

Klassenvererbungspraxis in Python, wie in sklearn zu sehen
Fallklasse in Python
[Python] Klassenvererbung, überschreiben
Klassennotation in Python
Einführung in Python in der Praxis (PiP)
[Hikari-Python] Kapitel 09-03 Klasse (Vererbung)
Verwenden Sie Stoff wie in Python (Stoff3)
In Python-Klassenvariablen versteckte Landminen
Lesen Sie PNG-Chunks in Python (Klassenausgabe)
Untersuchen Sie die Klasse eines Objekts mit Python
Algorithmus (Segmentbaum) in Python (Übung)
Generieren Sie eine erstklassige Sammlung in Python
Implementieren Sie __eq__ usw. generisch in der Python-Klasse
Übung, dies in Python zu verwenden (schlecht)
Python: [Vererbung] Wiederverwenden von Superklassenkonstruktoren in Unterklassen
Trump-Klasse in Python (mit Vergleich)
Verwendung von __slots__ in der Python-Klasse
Generieren Sie eine Klasse aus einer Zeichenfolge in Python
Python # Vererbung (Vererbung)
Verwenden Sie Python für formatierte Ausgaben wie C / C ++ printf
Versuchen Sie, das Problem der Python-Klassenvererbung zu lösen
Unterschied zwischen Variablen und Selbst. Variablen in der [Python] -Klasse
Ich habe eine Klasse in Python3 und Java geschrieben
Finden Sie in Python Primzahlen mit einem möglichst kurzen Code
Boost.NumPy Tutorial zum Erweitern von Python in C ++ (Übung)
Probleme mit pseudo-privaten Python-Variablen und Klassenvererbung
So geben Sie "Ketsumaimo" standardmäßig in Python aus
Verwenden Sie Python im Docker-Container als Pycharm-Interpreter
Grundlegende Geschichte der Vererbung in Python (für Anfänger)
Quadtree in Python --2
Python in der Optimierung
CURL in Python
Metaprogrammierung mit Python
Python 3.3 mit Anaconda
[Python] -Klasse, Instanz
Geokodierung in Python
SendKeys in Python
"Kanrika" die Python-Klasse
Metaanalyse in Python
Unittest in Python
Über Python, Klasse
Epoche in Python
Zwietracht in Python
Deutsch in Python
DCI in Python
Quicksort in Python
nCr in Python
Informationen zur Python-Vererbung
Plink in Python
Konstante in Python
FizzBuzz in Python
SQLite in Python
Schritt AIC in Python
Mein sklearn (Python)
LINE-Bot [0] in Python
CSV in Python
Reverse Assembler mit Python
Reflexion in Python