2015-09-03 15 views
7

PyCharm warnt mich Call to __init__ of super class is missedAbstrakte Basisklasse: raise NotImplementedError() in `__init __. Py`?

class AbstractBase(object): 
    def __init__(self): 
     raise NotImplementedError() 

class RealChild(AbstractBase): 
    def __init__(self): 
     #super(RealChild, self).__init__() #### 
     print('do stuff') 

child=RealChild() 

Aber wenn ich es nennen, wird die Klasse AbstractBaseNotImplementedError erhöhen.

Ich bin ein Schaf und nicht wissen, wie es weitergehen :-)

+6

Related: http://stackoverflow.com/questions/14972631/python-abstract-classes-how-to-discourage-instantiation – juanchopanza

Antwort

5

Sie könnten etwas tun g Art-of hässlich und überprüfen Sie die Art des self in der Initialisierer abstrakten Art, um sicherzustellen, dass es subtyped wurde:

class AbstractBase (object): 
    def __init__ (self): 
     if type(self) is AbstractBase: 
      raise NotImplementedError 

Ich denke, ein „normaler“ Ansatz wäre einfach nicht den abstrakten Basistyp aussetzen und erwarten, dass Benutzer es nicht erstellen.

+0

Wie kann ich den abstrakten Basistyp nicht freilegen? Andere Entwickler müssen eine Unterklasse erstellen. – guettli

+0

Entwickler ja, aber Benutzer nicht. Stellen Sie es nur Entwicklern zur Verfügung, die wissen, dass es nicht instanziiert sein sollte. Im Allgemeinen sollten Sie nicht zu weit gehen, um Regeln zu erzwingen, aber dokumentieren Sie es einfach und erwarten Sie, dass die Leute es richtig machen. – poke

+0

Ich verstehe es immer noch nicht. Meine Benutzer wissen, wie man einen Webbrowser benutzt. Das weiß nicht, dass Python eine Programmiersprache ist. Ich denke, "stelle den abstrakten Basistyp nicht frei" funktioniert in meinem Fall nicht. – guettli

0

In der abstrakten Klasse die Ausnahme in der Funktion init ersetzen mit

pass 

Dieser Ausnahme verwendet wird, zu verhindern, Sie von der neuen Instanz der abstrakten Klasse initialisieren (es ist abstrakt, so können Sie nicht) Also entweder 'pass' oder nicht auf pycharm hören und nicht super anrufen

+2

Technisch gesehen, die Ausnahme verhindert, dass Sie ein neues Objekt initialisieren, nicht erstellen. 'a = A .__ new __ (A)' funktioniert gut. – chepner

4

Sie könnten using the abc Abstract Base Class module betrachten __init__ als abstrakt zu markieren, und dann gehen Sie vor und die Super __init__ aus der Unterklasse aufrufen (und, wie DorElias suggested, geben die Super __init__ eine triviale Implementierung von pass):

from abc import ABCMeta, abstractmethod 


class AbstractBase(object, metaclass=ABCMeta): 
    @abstractmethod # This method must be overridden... 
    def __init__(self): 
     print("...but can still be called via super by subclasses have shared construction logic") 
     pass 


class RealChild(AbstractBase): 
    def __init__(self): 
     super().__init__() # Won't do anything, UNTIL the day you decide all subclasses of AbstractBase need shared logic 
     print('do stuff') 


child = RealChild() 

wenn Sie über parent = AbstractBase() oder parent = AbstractBase.__new__(AbstractBase) zu instanziiert versuchen, erhalten Sie eine Fehlermeldung erhalten:

TypeError: Can't instantiate abstract class AbstractBase with abstract methods init

Sie haben also Ihre unantastbare abstrakte Sicherheit, aber gleichzeitig sind Sie immer noch in der Lage, alle Kindklassenkonstruktionen zu ändern, indem Sie die Basisklassenkonstruktion ändern, wie es richtig und richtig ist.

+0

Dies sollte die akzeptierte Antwort sein. Wenn die Absicht darin besteht, ein ABC zu haben, sollte man sich darüber im Klaren sein - das Auslösen einer Ausnahme im Konstruktor ist nicht der richtige Weg. – BoltzmannBrain

Verwandte Themen