2017-11-28 2 views
1

Ich frage mich, ob in Python (3) eine abstrakte Klasse konkrete Methoden haben kann.
Obwohl dies scheint, ich bin nicht sicher, ob dies der richtige Weg zur Arbeit ist dies in Python zu tun:Python Abstract Klasse mit konkreten Methoden

from abc import ABCMeta, abstractclassmethod, abstractmethod 

class MyBaseClass: 
    __metaclass__ = ABCMeta 

    @property 
    @abstractmethod 
    def foo_prop(self): 
     """Define me""" 
     pass 

    @abstractclassmethod 
    def get_something(cls, param1, param2, param3): 
     """This is a class method, override it with @classmethod """ 
     pass 

    @classmethod 
    def get(cls, param1, param2): 
     """Concrete method calling an abstract class method and an abstract property""" 
     if param1 < cls.foo_prop: 
      raise Exception() 
     param3 = param1 + 42 
     item = cls.get_something(param1, param2, param3) 
     return item 


class MyConcreteClassA(MyBaseClass): 
    """Implementation """ 

    foo_prop = 99 

    @classmethod 
    def get_something(cls, param1, param2, param3): 
     return cls.foo_prop + param1 + param2 + param3 


class MyConcreteClassB(MyBaseClass): 
    """Implementation """ 

    foo_prop = 255 

    @classmethod 
    def get_something(cls, param1, param2, param3): 
     return cls.foo_prop - param1 - param2 - param3 

Im Beispiel ist die abstrakte Klasse MyBaseClass hat: foo_prop

  • eine abstrakte Eigenschaft, dass in den Unterklassen wird
    • die einzige Art und Weise definiert wird ich dies zu erklären finden konnte, war eine abstrakte „Eigenschaft Methode“
    • zu erstellen
  • eine abstrakte Klasse Methode get_something die
  • eine konkrete Methode in den Unterklassen implementiert wird get, dass abwechselnd die (noch nicht definiert ist) abstrakte Methode und Eigenschaft oben erwähnt verwendet.

Fragen:

  1. Gibt es einen besseren Weg, um eine abstrakte Eigenschaft zu definieren? Wäre es sinnvoller, eine konkrete Eigenschaft in MyBaseClass auf None zu definieren und sie nur in den Unterklassen neu zu definieren?

  2. Kann ich abstrakte und konkrete Methoden in einer abstrakten Klasse kombinieren, wie im Beispiel gezeigt?

  3. Wenn ja, ist es immer sinnvoll, die Klasse abstrakt zu deklarieren oder kann eine konkrete Klasse abstrakte Methoden haben (in diesem Fall sollte sie niemals direkt instanziiert werden).

Dank

Antwort

1
  1. Nach the docs (Text in Klammern und Code-Formatierung von mir):

    seit Version Veraltet [@abstractproperty ist] 3.3: Es ist nun möglich property zu verwenden , property.getter(), property.setter() und property.deleter() mit abstractmethod(), wodurch dieser Dekorator überflüssig wird.

    so denke ich, dass Sie es richtig machen.

  2. Sie können dies tun, oder zumindest nach meiner Erfahrung war es kein Problem. Vielleicht kann jemand anderes einen anderen Ratschlag geben, aber dieser Rat wird wahrscheinlich die Form "Erbschaft ist schlecht" annehmen. Obwohl ich in den Dokumenten nichts explizit darüber sehe, this section shows an example wobei eine abstrakte Methode, konkrete Methode und Klassenmethode alle in einem ABC definiert sind.

  3. Ich glaube, dass Sie immer noch die Klasse abstrakt erklären müssen, um @abstractmethod und ähnliche Dekoratoren zu verwenden.Wenn Sie die Metaklasse als ABC definieren, kann die Klasse erst instanziiert werden, wenn alle abstrakten Methoden definiert sind. Das klingt nach dem von Ihnen gewünschten Verhalten. Ich denke, Sie müssen es abstrakt deklarieren, wenn Sie sich nicht auf die Dokumentation verlassen wollen soll "Regel für diese Klasse nicht instanziieren". Als Neben you can declare your abstract class with:

    from abc import ABC 
    class MyBaseClass(ABC): 
        # ... 
    

    von abc Vererbungs anstatt manuell die Metaklasse einstellen. Ich denke, dass diese Konstruktion bevorzugt wird.

Verwandte Themen