Lass mich damit beginnen, es ist keine Wiederholung von
Warum wird __init__ nicht aufgerufen, wenn __new__ ohne Argumente aufgerufen . Ich habe versucht, einige Beispielcode für __new__
und __init__
sorgfältig zu konstruieren, die keine Erklärung finden kann, die ich finden kann.
Die grundlegenden Parameter:
__init__
-Methode, die wiederum eine _parse
-Methode _parse
in Unterklassen super
vorsichtig zu verwenden, um die Probleme zu vermeiden
Python-Protokollierung: Warum wird __init__ zweimal aufgerufen?
Wie auch immer, __init__
sollte nach __new__
aufgerufen werden und für jede Erklärung, warum einige Beispiele unten nicht funktionieren, scheint es mir möglich zu sein, auf andere Fälle hinzuweisen, die funktionieren und die Erklärung ausschließen.
Wenn Sie den Code ausführen, können Sie sehen, dass bei jedem Aufruf von __new__
angezeigt wird, "welche Tür" durch welchen Typ durchgeht. Ich kann die gleiche "Tür" mit dem gleichen "Typ" -Objekt verlassen und __init__
in einem Fall aufgerufen haben und nicht den anderen. Ich habe mir den mro der "Calling" -Klasse angeschaut und das bietet keinen Einblick, da ich diese Klasse (oder eine Unterklasse wie in CCC) aufrufen kann und __init__
called.
Ende Anmerkungen:
Die NotMine
-Bibliothek, die ich benutze, ist die Genshi MarkupTemplate und der Grund dafür, dass keine Factory-Design-Methode verwendet wird, ist, dass ihr TemplateLoader ein benötigt defaultClass zu konstruieren. Ich weiß es nicht, bis ich mit dem Parsen anfange, was ich in __new__
mache. Es gibt eine Menge cooler Voodoo-Magie, die Genshi-Loader und Templates machen, die sich lohnen.
Ich kann eine unveränderte Instanz ihres Loaders ausführen und derzeit funktioniert alles, solange ich NUR die ABC-Klasse (abstrakte Sortierreihenfolge) als Standard übergebe. Die Dinge funktionieren gut, aber dieses unerklärliche Verhalten ist später ein fast sicherer Fehler.
UPDATE:
Ignacio, die Topline-Frage genagelt, wenn das zurückgegebene Objekt keine "Instanz von" cls ist, dann wird __init__
nicht aufgerufen. Ich finde, dass das Aufrufen des "Konstruktors" (zB AA(args..)
falsch ist, da es __new__
wieder aufruft und Sie wieder da sind, wo Sie angefangen haben. Sie könnten ein Argument ändern, um einen anderen Pfad zu wählen. co_de% zweimal statt unendlich Eine Arbeitslösung besteht darin, ABC.__new__
oben als:
Beachten Sie die letzten Zeilen. Kein Aufruf von class ABC
, wenn es sich um eine "andere" Klasse handelt, macht für mich keinen Sinn, BESONDERS wenn die "different" -Klasse noch eine Unterklasse der Klasse ist, die __init__
aufruft. Ich mag den obigen Schnitt nicht, aber am wenigsten verstehe ich jetzt die Regeln.
Aus der Dokumentation :
Wenn
__new__()
keine Instanz von cls zurückgibt, wird die__init__()
-Methode der neuen Instanz nicht aufgerufen.
Dies ist, damit __new__()
eine neue Instanz einer anderen Klasse zurückgibt , die stattdessen ihr eigenes __init__()
hat. Sie müssen feststellen, ob Sie ein neues cls erstellen, und andernfalls den entsprechenden Konstruktor aufrufen.
Nur meine zwei Cent hier, aber warum benutzt du nicht die Python-Ente-Eingabe, um Genshi etwas zu geben, das sich wie eine Klasse verhält?
Ich habe einen kurzen Blick auf Genshi Quellcode geworfen und die einzigen Anforderungen, die ich habe sah auf dem 'class' Parameter für den TemplateLoader ist, dass es mit den gegebenen Argumenten aufrufbar ist.
Ich denke, es wäre einfacher, eine Klasse mit einer Factory-Funktion zu verspotten, die die tatsächlich erstellte Instanz zurückgibt.