Ich habe eine Situation wie diese ...
class Outer(object):
def some_method(self):
# do something
class Inner(object):
def __init__(self):
self.Outer.some_method() # <-- this is the line in question
Wie kann ich von der Outer
Klasse aus auf die Methode der Inner
Klasse zugreifen ?
python
scope
nested
inner-classes
T. Stone
quelle
quelle
self.<original_parent_name>
und die ursprüngliche Klasse abzurufen, nicht die neue Klasse, aus der sie eine Unterklasse sind . Ich hoffe, dass die Leute, die dies lesen, dieses schwierige Szenario visualisieren und den Sinn solcher Fragen erkennen können.Antworten:
Die Methoden einer verschachtelten Klasse können nicht direkt auf die Instanzattribute der äußeren Klasse zugreifen.
Beachten Sie, dass eine Instanz der äußeren Klasse nicht unbedingt vorhanden ist, selbst wenn Sie eine Instanz der inneren Klasse erstellt haben.
Tatsächlich wird häufig empfohlen, keine verschachtelten Klassen zu verwenden, da die Verschachtelung keine bestimmte Beziehung zwischen der inneren und der äußeren Klasse impliziert.
quelle
Sie versuchen, von der inneren Klasseninstanz auf die Klasseninstanz von Outer zuzugreifen. Verwenden Sie also einfach die Factory-Methode, um die innere Instanz zu erstellen und die äußere Instanz an sie zu übergeben.
quelle
Vielleicht bin ich verrückt, aber das scheint in der Tat sehr einfach zu sein - die Sache ist, deine innere Klasse in eine Methode der äußeren Klasse zu verwandeln ...
Plus ... "self" wird nur von Konventionen verwendet, also können Sie dies tun:
Es könnte beanstandet werden, dass Sie diese innere Klasse dann nicht von außerhalb der äußeren Klasse erstellen können ... aber das ist nicht wahr:
dann irgendwo meilenweit entfernt:
Schieben Sie das Boot sogar ein wenig heraus und erweitern Sie diese innere Klasse (NB, damit super () funktioniert. Sie müssen die Klassensignatur von mooble in "class mooble (object)" ändern.
später
mrh1997 sprach einen interessanten Punkt über die nicht häufige Vererbung innerer Klassen an, die mit dieser Technik geliefert wurden. Aber es scheint, dass die Lösung ziemlich einfach ist:
quelle
Wollen Sie Vererbung verwenden, anstatt Klassen wie diese zu verschachteln? Was Sie tun, macht in Python keinen Sinn.
Sie können auf die
Outer
some_method des 'zugreifen, indem Sie nur aufOuter.some_method
die Methoden der inneren Klasse verweisen , aber es wird nicht so funktionieren, wie Sie es erwarten. Wenn Sie dies beispielsweise versuchen:... erhalten Sie beim Initialisieren eines
Inner
Objekts einen TypeError , daOuter.some_method
erwartet wird, dass eineOuter
Instanz als erstes Argument empfangen wird . (Im obigen Beispiel versuchen Sie im Grunde,some_method
als Klassenmethode von aufzurufenOuter
.)quelle
Sie können einfach über die Metaklasse auf die äußere Klasse zugreifen: Nach der Erstellung der äußeren Klasse überprüfen Sie das Attribut dikt für alle Klassen (oder wenden Sie jede Logik an, die Sie benötigen - meine ist nur ein triviales Beispiel) und legen Sie die entsprechenden Werte fest:
Mit diesem Ansatz können Sie problemlos zwei Klassen untereinander binden und verweisen.
quelle
Ich habe Python-Code erstellt, um eine äußere Klasse aus der inneren Klasse zu verwenden , basierend auf einer guten Idee aus einer anderen Antwort auf diese Frage. Ich denke, es ist kurz, einfach und leicht zu verstehen.
Der Hauptcode "produktionsbereit" (ohne Kommentare usw.). Denken Sie daran, alle Werte in spitzen Klammern (z. B.
<x>
) durch den gewünschten Wert zu ersetzen .Erläuterung der Funktionsweise dieser Methode (grundlegende Schritte):
Erstellen Sie eine Funktion mit dem Namen
_subclass_container
, die als Wrapper für den Zugriff auf die Variable fungiertself
, einen Verweis auf die übergeordnete Klasse (aus Code, der in der Funktion ausgeführt wird).Erstellen Sie eine Variable mit dem Namen,
_parent_class
die auf die Variableself
dieser Funktion verweist, auf die die Unterklassen_subclass_container
zugreifen können (vermeidet Namenskonflikte mit anderenself
Variablen in Unterklassen).Geben Sie die Unterklasse / Unterklassen als Wörterbuch / Liste zurück, damit der Code, der die
_subclass_container
Funktion aufruft, auf die darin enthaltenen Unterklassen zugreifen kann.__init__
Empfangen Sie in der Funktion innerhalb der übergeordneten Klasse (oder wo immer dies erforderlich ist) die zurückgegebenen Unterklassen von der Funktion_subclass_container
in die Variablesubclasses
.Weisen Sie den
subclasses
Attributen der übergeordneten Klasse in der Variablen gespeicherte Unterklassen zu.Einige Tipps zur Vereinfachung von Szenarien:
Vereinfachen des Kopierens des Codes zum Zuweisen der Unterklassen zur übergeordneten Klasse und zum Verwenden in Klassen, die von der übergeordneten Klasse abgeleitet sind und deren
__init__
Funktion geändert wurde:Fügen Sie vor Zeile 12 den Hauptcode ein:
Fügen Sie dann in diese Funktion die Zeilen 5-6 (des Hauptcodes) ein und ersetzen Sie die Zeilen 4-7 durch den folgenden Code:
Ermöglichen der Zuordnung von Unterklassen zur übergeordneten Klasse, wenn viele / unbekannte Mengen von Unterklassen vorhanden sind.
Ersetzen Sie Zeile 6 durch den folgenden Code:
Beispielszenario, wo diese Lösung nützlich wäre und wo der übergeordnete Klassenname nicht zu erhalten sein sollte:
Eine Klasse mit dem Namen "a" (
class a:
) wird erstellt. Es hat Unterklassen, die darauf zugreifen müssen (das übergeordnete Element). Eine Unterklasse heißt "x1". In dieser Unterklasse wird der Codea.run_func()
ausgeführt.Dann wird eine andere Klasse mit dem Namen "b" erstellt, die von der Klasse "a" (
class b(a):
) abgeleitet ist. Danach wird ein Teil des Codes ausgeführtb.x1()
(Aufruf der Unterfunktion "x1" von b, einer abgeleiteten Unterklasse). Diese Funktion wird ausgeführta.run_func()
und ruft die Funktion "run_func" der Klasse "a" auf, nicht die Funktion "run_func" des übergeordneten Elements "b" (wie es sollte), da die in der Klasse "a" definierte Funktion auf referenziert gesetzt ist auf die Funktion der Klasse "a", da dies ihr Elternteil war.Dies würde Probleme verursachen (z. B. wenn die Funktion
a.run_func
gelöscht wurde) und die einzige Lösung ohne Umschreiben des Codes in der Klassea.x1
wäre die Neudefinition der Unterklassex1
mit aktualisiertem Code für alle Klassen, die von der Klasse "a" abgeleitet sind, was offensichtlich schwierig und nicht wert wäre es.quelle
Ich fand diese .
An Ihre Frage angepasst:
Ich bin sicher, Sie können irgendwie einen Dekorateur dafür schreiben oder so
Verwandte: Was ist der Zweck der inneren Klassen von Python?
quelle
Andere Möglichkeit:
quelle
Erweitern Sie @ tsnorris überzeugendes Denken, dass die äußere Methode eine statische Methode sein könnte :
Jetzt sollte die betreffende Leitung zu dem Zeitpunkt funktionieren, zu dem sie tatsächlich aufgerufen wird.
Die letzte Zeile im obigen Code gibt der inneren Klasse eine statische Methode, die ein Klon der äußeren statischen Methode ist.
Dies nutzt zwei Python-Funktionen: Funktionen sind Objekte und der Umfang ist textuell .
... oder aktuelle Klasse in unserem Fall. Daher können Objekte, die "lokal" zur Definition der äußeren Klasse (
Inner
undsome_static_method
) gehören, direkt in dieser Definition referenziert werden.quelle
Ein paar Jahre zu spät zur Party ... aber um die
@mike rodent
wundervolle Antwort zu erweitern, habe ich unten mein eigenes Beispiel gegeben, das zeigt, wie flexibel seine Lösung ist und warum sie akzeptiert werden sollte (oder hätte sein sollen) Antworten.Python 3.7
Ausgabe:
Wieder eine wundervolle Antwort, Requisiten an dich, Mike!
quelle
Es ist zu einfach:
Eingang:
Ausgabe
Klasse A func1
Klasse B func1
quelle
func1
. Und ebenso amüsant erstellen Sie einA
Inneres im Konstruktor vonB
, das absolut NICHT das äußere KlassenobjektA
dieses bestimmten istB
.