Es handelt sich um eine doppelte Frage, die einen theoretischen und einen praktischen Teil hat:
Bei der Unterklassifizierung von dict:
class ImageDB(dict):
def __init__(self, directory):
dict.__init__(self) # Necessary??
...
sollte dict.__init__(self)
aufgerufen werden, nur als "Sicherheits"-Maßnahme (z.B. für den Fall, dass es einige nicht-triviale Implementierungsdetails gibt, die von Bedeutung sind)? Besteht die Gefahr, dass der Code mit einer zukünftigen Version von Python nicht mehr funktioniert, wenn dict.__init__()
es no angerufen? Ich suche nach einem grundsätzlichen Grund, das eine oder das andere zu tun, hier (praktisch, indem ich dict.__init__()
sicher ist).
Meine Vermutung ist, dass wenn ImageDB.__init__(self, directory)
aufgerufen wird, ist self bereits ein neues, leeres dict-Objekt, und es besteht daher keine Notwendigkeit, die dict.__init__
(Ich möchte, dass das Diktat anfangs leer ist). Ist das richtig?
bearbeiten :
Die praktische Frage, die sich hinter der obigen Grundsatzfrage verbirgt, ist die folgende. Ich habe mir überlegt, dict zu unterklassifizieren, weil ich die db[ ]-Syntax recht häufig verwenden würde (anstatt ständig db.contents[ ] zu verwenden); die einzigen Daten (Attribute) des Objekts sind tatsächlich ein dict. Ich möchte der Datenbank ein paar Methoden hinzufügen (z. B. get_image_by_name()
, oder get_image_by_code()
zum Beispiel), und überschreiben Sie nur die __init__()
denn die Bilddatenbank wird durch das Verzeichnis definiert, in dem sie sich befindet.
Zusammengefasst Die (praktische) Frage könnte lauten: Was ist eine gute Implementierung für etwas, das sich wie ein Wörterbuch verhält, nur dass seine Initialisierung anders ist (es braucht nur einen Verzeichnisnamen) und dass es zusätzliche Methoden hat?
In vielen Antworten wurden "Fabriken" erwähnt. Ich schätze, es läuft alles auf Folgendes hinaus: Unterklassifizieren Sie dict, überschreiben Sie __init__()
und fügen Methoden hinzu, oder schreiben Sie eine (Fabrik-)Funktion, die ein Diktat zurückgibt, zu dem Sie Methoden hinzufügen? Ich neige dazu, die erste Lösung zu bevorzugen, weil die Fabrikfunktion ein Objekt zurückgibt, dessen Typ nicht angibt, dass es zusätzliche Semantik und Methoden hat, aber was denken Sie?
Bearbeiten 2 :
Aus den Antworten entnehme ich, dass es keine gute Idee ist, dict zu unterklassifizieren, wenn die neue Klasse "kein Wörterbuch" ist, und insbesondere, wenn ihre __init__
Methode kann nicht die gleichen Argumente wie dicts __init__
(was in der obigen "praktischen Frage" der Fall ist). Mit anderen Worten, wenn ich es richtig verstehe, scheint der Konsens zu sein: Wenn Sie eine Unterklasse bilden, müssen alle Methoden (einschließlich der Initialisierung) die gleiche Signatur wie die Methoden der Basisklasse haben. Dadurch kann isinstance(subclass_instance, dict) garantieren, dass subclass_instance.__init__()
kann verwendet werden wie dict.__init__()
zum Beispiel.
Eine andere praktische Frage taucht dann auf: wie sollte eine Klasse, die genau wie dict ist, mit Ausnahme der Initialisierungsmethode, implementiert werden? ohne subclassing? dies würde einige lästige Boilerplate-Code erfordern, nicht?
1 Stimmen
Eine Werksfunktion ist der richtige Weg. Wenn Sie die Funktion anpassen müssen Instanz Verhalten, dann sollten Sie eine Unterklasse erstellen. Wenn Sie einfach nur überschreiben wollen Initialisierung brauchen Sie nichts zu untergliedern, da sich Ihre Instanzen nicht von den Standardinstanzen unterscheiden. Denken Sie daran, dass init wird nicht als Teil der Schnittstelle der Instanz, sondern der Klasse betrachtet.
0 Stimmen
Soweit ich es sehe, wäre es bei diesem Problem am besten, die
__getitem__
Methode zu Ihrer ImageDB hinzuzufügen, anstatt ein dict zu unterklassifizieren, denn es ist no ein Diktat. Damit können Sie tun, was Sie wollen, sin mit all diesen Methoden wiepop()
die für Ihre Klasse ungeeignet zu sein scheinen.0 Stimmen
@gs: Guter Punkt, über pop; es ist in der Tat, zumindest für den Moment, irrelevant (der Inhalt der Datenbank ist nur bei der Initialisierung definiert). Ich denke, dass es in der Tat am besten ist, wenn die Implementierung eng an die notwendigen Funktionen angepasst ist.