Die abstrakten Methoden des abc-Moduls von Python unterscheiden nicht zwischen Klassen und Instanzen.

Python hatte keine abstrakte Klasse oder Schnittstelle. Mit dem Hinzufügen des Moduls abc (Abkürzung für abstrakte Basisklasse) ist es jedoch möglich geworden, dies mithilfe von Dekoratoren zu erreichen. Lassen Sie uns diesmal experimentieren, um herauszufinden, unter welchen Bedingungen die abstrakte Klasse tatsächlich einen Fehler ausgibt.

Die abstrakte Klasse gibt beim Erstellen einer Instanz einen Fehler aus

Abstrakte Klassen erzwingen die Funktionen (Methoden), die sie implementieren sollen. Wenn Sie es nicht in Python implementieren, wird nur dann ein Fehler angezeigt, wenn Sie eine implementierte Klasse (genauer gesagt eine nicht implementierte Klasse) instanziieren. Selbst wenn die Klasse die abstrakte Methode nicht implementiert, verursacht sie daher keinen Fehler, wenn Sie nur darauf zugreifen, um die Klassenmethode zu verwenden. In den folgenden Fällen tritt der Fehler nur auf, wenn die abstrakte Klasse und ihre Unterklassen instanziiert werden.

from abc import *

class Abstract(object, metaclass=ABCMeta):

    @classmethod
    @abstractmethod
    def hello(cls):
        print("Abstract hello")

class Implement(Abstract):
    pass

Abstract.hello()
# => Abstract hello
Implement.hello()
# => Abstract hello

# Abstract()
# TypeError: Can't instantiate abstract class Abstract with abstract methods hello

# Implement()
# TypeError: Can't instantiate abstract class Implement with abstract methods hello

Natürlich müssen Sie beim Instanziieren eine abstrakte Methode implementieren (definieren). Selbst wenn Sie eine andere Methode erstellen, wird diese nicht als implementiert erkannt. Mit anderen Worten, es erfüllt nicht die Kriterien des Erstellers der abstrakten Klasse. Lass es uns überprüfen.

from abc import *

class Abstract(object, metaclass=ABCMeta):

    @classmethod
    @abstractmethod
    def hello(cls):
        print("Abstract hello")

class Implement(Abstract):
    @classmethod
    def say(cls):
        print("Implement class-method say")

    def yeah(self):
        print("Implement instance-method yeah")

Implement()

# => TypeError: Can't instantiate abstract class Implement with abstract methods hello

Es wird nicht zwischen abstrakten Klassenmethoden und Instanzmethoden unterschieden

Definieren Sie eine Klassenmethode einer abstrakten Klasse als abstrakte Methode. Wenn Sie in dieser Unterklasse eine Methode mit demselben Namen wie eine Instanzmethode definieren, tritt kein Fehler auf. Vielleicht ist Python alles Objekte und nicht zu unterscheiden, so dass es nur den Namen bestimmt, nicht den Typ der Methode.

from abc import *

class Abstract(object, metaclass=ABCMeta):

    @classmethod
    @abstractmethod
    def hello(cls):
        print("Abstract hello")

class Implement(Abstract):
    def hello(self):
        print("Implement hello")

impl = Implement()
impl.hello()

# => Implement hello

Definieren wir eine abstrakte Klassenmethode als Instanzmethode und eine abstrakte Instanzmethode als Klassenmethode. Der Fehler ist diesmal auf das Fehlen der Klassenmethode Hallo zurückzuführen. Da die Unterklasse Hallo eine Instanz und die übergeordnete Klasse Hallo eine abstrakte Methode ist, führt die Klassenmethode zu einem Fehler, da Hallo nicht implementiert ist. Es verursacht keinen Fehler beim Zugriff auf die Klasse, aber es sagt, dass es nutzlos ist, da keine Methode angewiesen ist, es zu verwenden.

from abc import *

class Abstract(object, metaclass=ABCMeta):

    @classmethod
    @abstractmethod
    def hello(cls):
        print("Abstract hello")

    def say(self):
        print("Abstract say")

class Implement(Abstract):

    def hello(self):
        print("Implement hello")

    @classmethod
    def say(cls):
        print("Implement say")

impl = Implement()
impl.hello()
impl.say()
# =>
# Implement hello
# Implement say

# Implement.hello()
# hello() missing 1 required positional argument: 'self'

Implement.say()

# =>
# Implement say

Wie weit können Sie die Implementierung erzwingen?

In diesem Experiment haben wir festgestellt, dass es nicht möglich ist, zwischen Klassenmethoden und Instanzmethoden zu unterscheiden. Möglicherweise haben Sie den Fehler selbst vorbereitet, oder Sie haben eine Methode in den abc-Moduloptionen. Beachten Sie jedoch, dass die normale Verwendung nur die Implementierung von Methoden mit demselben Namen einschränken kann.

Recommended Posts

Die abstrakten Methoden des abc-Moduls von Python unterscheiden nicht zwischen Klassen und Instanzen.
Python-Klassen und -Instanzen, Instanzmethoden
Binden Sie Methoden an Python-Klassen und -Instanzen
Zusammenfassung der Unterschiede zwischen PHP und Python
Die Antwort von "1/2" unterscheidet sich zwischen Python2 und 3
Berücksichtigung des Unterschieds zwischen ROC-Kurve und PR-Kurve
[Python] Ruft die Liste der im Modul definierten Klassen ab
Visualisierung der Verbindung zwischen Malware und dem Callback-Server