2016-12-02 3 views
0

Erster Tag lernen Python, bitte entschuldigen Sie die grundlegende Frage.Lernen Python: Implementieren einer virtuellen Methode

Angenommen, ich habe eine Aufgabe gegeben, die eine nicht implementierte Methode enthält, die ich implementieren müssen, z:

class myclass(): 
    def __init__(self) 
    self.unimplementedmethod = False 

Was ist der richtige Weg, dies in einem instantiierten Objekt zu implementieren? Ich möchte die Basisklasse in keiner Weise ändern. Ich habe experimentiert und gefunden der folgende Code scheint zu funktionieren, aber ist es richtig/guter Stil?

def methodimplementation(): 
    print("method called") 

myobject = myclass() 
myobject.unimplementedmethod=methodimplementation 

Ist das der richtige Weg? Oder sollte ich etwas anderes tun, als vielleicht zuerst eine abgeleitete Klasse zu erstellen, die Methoden darin zu implementieren und dann ein Objekt basierend auf der abgeleiteten Klasse zu instanziieren? Was ist die beste Vorgehensweise?

+1

Sie sollten die Klasse ableiten, ja. Und eine nicht implementierte Methode sollte nicht den Wert "False" haben, sondern stattdessen (falls vorhanden) tatsächliche Methoden sein, die den Singleton 'NotImplemented' zurückgeben. – L3viathan

+0

Danke. Dies ist aus dem Open-Source-Projekt "Printrun". P. Verdammt schnell! –

+1

Ich weiß, dass dies keine Code-Überprüfung ist, aber Sie brauchen '()' nicht in 'class myclass():' (Sie sollten jedoch 'object' immer ableiten, wenn Sie Python 2 schreiben). – Tobias

Antwort

1

Sie müssen die Basisklasse Unterklasse:

class myclass(): 
    def some_method(): 
     raise NotImplementedError 

class my_subclass(myclass): 
    def some_method(): 
     print("method called") 
0

Sie einen abstract base class erstellen möchten. Dazu müssen Sie abc.ABCMeta in Ihrer Basisklasse erben. Wenn Sie die Methode dann als abstrakt definieren, müssen Sie sie mit @abstractmethod dekorieren. Zum Beispiel:

from abc import ABCMeta, abstractmethod 

class BaseClass(ABCMeta): 
    @abstractmethod 
    def my_method(): 
     pass 

Dann können Sie das Kind Klasse erstellen, wie:

class MyChildClass(BaseClass): 
    def my_method(): 
     print 'my method' 
0

Die gute Art und Weise Subklassen verwendet, aber wenn Sie es nicht tun, hier ist ein Weg, um den Zugriff auf self von einer einfachen Funktion nicht in einer Klasse definiert:

class Bar: 

    def __init__(self): 
     pass 

    def foo(self): 
     try: 
      self._foo(self) 
     except AttributeError: 
      raise NotImplementedError 

    def set_foo(self, function): 
     setattr(self, '_foo', function) 

    def another_method(self): 
     print "Another method from {}".format(self) 


def foo(self): 
    self.another_method() 

bar = Bar() 
bar.set_foo(foo) 

bar.foo() 

So definieren def foo(self) eine Funktion mit einem Argument self, wie ein Verfahren. Diese Funktion ruft eine Instanzmethode another_method auf.

Bar.set_foo Erstellen Sie ein neues Attribut _foo in der Instanz Bar.

Schließlich Bar.foo versuchen, auf self._foo mit self als Argument zuzugreifen. Wenn _foo nicht existiert, löst Bar.foo einen NotImplementedError wie erwartet aus.

Wie Sie können auf self von foo ohne Unterklassen zugreifen.

Verwandte Themen