I ve created some Python code to use an outer class from its inner class, based on a good idea from another answer for this question. I think it s short, simple and easy to understand.
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}
The main code, "production ready" (without comments, etc.). Remember to replace all of each value in angle brackets (e.g. <x>
) with the desired value.
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>}
Explanation of how this method works (the basic steps):
Create a function named _subclass_container
to act as a wrapper to access the variable self
, a reference to the higher level class (from code running inside the function).
Create a variable named _parent_class
which is a reference to the variable self
of this function, that the sub-classes of _subclass_container
can access (avoids name conflicts with other self
variables in subclasses).
Return the sub-class/sub-classes as a dictionary/list so code calling the _subclass_container
function can access the sub-classes inside.
In the __init__
function inside the higher level class (or wherever else needed), receive the returned sub-classes from the function _subclass_container
into the variable subclasses
.
Assign sub-classes stored in the subclasses
variable to attributes of the higher level class.
A few tips to make scenarios easier:
Making the code to assign the sub classes to the higher level class easier to copy and be used in classes derived from the higher level class that have their __init__
function changed:
Insert before line 12 in the main code:
def _subclass_init(self):
Then insert into this function lines 5-6 (of the main code) and replace lines 4-7 with the following code:
self._subclass_init(self)
Making subclass assigning to the higher level class possible when there are many/unknown quantities of subclasses.
Replace line 6 with the following code:
for subclass_name in list(subclasses.keys()):
setattr(self, subclass_name, subclasses[subclass_name])
Example scenario of where this solution would be useful and where the higher level class name should be impossible to get:
A class, named "a" (class a:
) is created. It has subclasses that need to access it (the parent). One subclass is called "x1". In this subclass, the code a.run_func()
is run.
Then another class, named "b" is created, derived from class "a" (class b(a):
). After that, some code runs b.x1()
(calling the sub function "x1" of b, a derived sub-class). This function runs a.run_func()
, calling the function "run_func" of class "a", not the function "run_func" of its parent, "b" (as it should), because the function which was defined in class "a" is set to refer to the function of class "a", as that was its parent.
This would cause problems (e.g. if function a.run_func
has been deleted) and the only solution without rewriting the code in class a.x1
would be to redefine the sub-class x1
with updated code for all classes derived from class "a" which would obviously be difficult and not worth it.