I've seen a few "solutions" to this, but the solution every time seems to be "Don't use nested classes, define the classes outside and then use them normally". I don't like that answer, because it ignores the primary reason I chose nested classes, which is, to have a pool of constants (associated with the base class) accessible to all sub-class instances which are created.
Here is example code:
class ParentClass:
constant_pool = []
children = []
def __init__(self, stream):
self.constant_pool = ConstantPool(stream)
child_count = stream.read_ui16()
for i in range(0, child_count):
children.append(ChildClass(stream))
class ChildClass:
name = None
def __init__(self, stream):
idx = stream.read_ui16()
self.name = constant_pool[idx]
All classes are passed a single param, which is a custom bitstream class. My intention is to have a solution that does not require me to read the idx value for ChildClass while still in the ParentClass. All child-class stream reading should be done in the child class.
This example is over simplified. The constant pool is not the only variable i need available to all subclasses. The idx variable is not the only thing read from the stream reader.
Is this even possible in python? Is there no way to access the parent's information?
You don't need two classes here. Here's your example code written in a more concise fashion.
Welcome to Python. Classes are mutable at runtime. Enjoy.
Your question uses the word subclass, so I'm keying from that to interpret your question. As with the others who have answered, I am not certain I understand what you are looking for.
This code uses inheritance to derive ChildClass from ParentClass (and all methods, etc). The constant_pool is an attribute of ParentClass itself, though it is OK to treat as an attribute of any instance of ParentClass or ChildClass (saying
self.constant_pool
withinChildClass.__init__
would be equivalent to the above but, in my view, misleading).Nesting the class definitions is not necessary. Nesting the definition of ChildClass within ParentClass just means that ChildClass is an attribute of ParentClass, nothing more. It does not make instances of ChildClass inherit anything from ParentClass.
Another alternative design to consider:
When you find yourself trying to use classes as namespaces, it might make more sense to put the inner classes into a module of their own and make what were the attributes of the outer class global variables. In other words, if you never intend to instantiate your
ParentClass
, then it's just serving as a glorified module.Global variables get a bad rap in most programming languages, but they are not truly global in Python, and are nicely encapsulated to the module.
Despite my "bit patronizing" comment (fair play to call it that!), there are actually ways to achieve what you want: a different avenue of inheritance. A couple:
Write a decorator that introspects a class just after it's declared, finds inner classes, and copies attributes from the outer class into them.
Do the same thing with a metaclass.
Here's the decorator approach, since it's the most straightforward:
Here is a simple example of its use:
However, I can't help but think some of the ideas suggested in other answers would serve you better.
You can access the parent class through its name:
Then again, I'm not sure I understand what you are trying to achieve.
Well, the following works (further simplified from your example). Note that you don't have to "declare" member variables at class level like C++/C#/Java etc, just set them on
self
within__init__
:Note that you could still do the same sort of thing without the child classes being nested.