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.
class higher_level__unknown_irrelevant_name__class:
def __init__(self, ...args...):
...other code...
# Important lines to access sub-classes.
subclasses = self._subclass_container()
self.some_subclass = subclasses["some_subclass"]
del subclasses # Free up variable for other use.
def sub_function(self, ...args...):
...other code...
def _subclass_container(self):
_parent_class = self # Create access to parent class.
class some_subclass:
def __init__(self):
self._parent_class = _parent_class # Easy access from self.
# Optional line, clears variable space, but SHOULD NOT BE USED
# IF THERE ARE MULTIPLE SUBCLASSES as would stop their parent access.
# del _parent_class
class subclass_2:
def __init__(self):
self._parent_class = _parent_class
# Return reference(s) to the subclass(es).
return {"some_subclass": some_subclass, "subclass_2": subclass_2}
Der Hauptcode "produktionsbereit" (ohne Kommentare usw.). Denken Sie daran, alle Werte in spitzen Klammern (z. B. <x>
) durch den gewünschten Wert zu ersetzen .
class <higher_level_class>:
def __init__(self):
subclasses = self._subclass_container()
self.<sub_class> = subclasses[<sub_class, type string>]
del subclasses
def _subclass_container(self):
_parent_class = self
class <sub_class>:
def __init__(self):
self._parent_class = _parent_class
return {<sub_class, type string>: <sub_class>}
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 fungiert self
, 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 Variable self
dieser Funktion verweist, auf die die Unterklassen _subclass_container
zugreifen können (vermeidet Namenskonflikte mit anderen self
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 Variable subclasses
.
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:
def _subclass_init(self):
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:
self._subclass_init(self)
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:
for subclass_name in list(subclasses.keys()):
setattr(self, subclass_name, subclasses[subclass_name])
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 Code a.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ührt b.x1()
(Aufruf der Unterfunktion "x1" von b, einer abgeleiteten Unterklasse). Diese Funktion wird ausgeführt a.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 Klasse a.x1
wäre die Neudefinition der Unterklasse x1
mit aktualisiertem Code für alle Klassen, die von der Klasse "a" abgeleitet sind, was offensichtlich schwierig und nicht wert wäre es.