Search code examples
pythonclassinner-classesinstance-variables

Can an inner class retrieve the instance of the top class?


The program I am working on uses nested classes. The top class is named Brain which has two inner classes, Neuron and Axon. The inner classes need to be able to modify the instance variables of the top class.

Brain keeps track of how many neurons and axons have been instantiated. Neuron holds information regarding its action potential and its outputs. Axon determines how to traverse the energy from one neuron to another. This way whenever I instantiate a neuron, it is saved within the instance of the brain. The same goes for the axon.


This is my code so far:

class Brain(object):
    def __init__(self):
        self.neurons = []
        self.axons = []

    class Neuron(object):
        def __init__(self, pos, AP_Energy, AP_threshold):
            # General attributes
            self.outputs = {}
            self.Energy = 0
            self.x, self.y = pos[0], pos[1]

            # Action Potential attributes
            self.AP_Energy = AP_Energy
            self.AP_threshold = AP_threshold

            """Append self to instance
               of Brain in neurons"""

        def add(self, value): self.Energy += value
        def link(self, neuron, weight): self.outputs[neuron] = weight

        def act(self):
            for neuron in self.outputs.keys():
                """Append Axon(self, neuron) to
                   instance of Brain in axons"""

    class Axon(object):
        def __init__(self, n1, n2):
            # Neurons
            self.n1, self.n2 = n1, n2

            # Action Potential attributes
            self.wavelength = sqrt((5*n1.AP_Energy)/3)
            self.distance = sqrt((n2.x-n1.x)**2+(n2.y-n1.y)**2)

        def action_potential(self): # Bunch of math stuff

The idea is that you can create neurons without having to include the instance of the brain as one of its arguments. Therefore, if I want to create an instance of Brain with two neurons, it should appear as so:

EntityA = Brain()
EntityA.Neuron((0, 1), 15, 24)
EntityA.Neuron((4, 2), 30, 41)

And if I need to call add() from the first neuron in EntityA, I should be able to refer to it as EntityA.neurons[0].add(value) since as I create the neurons it should automatically append itself to the list.

How would I go about doing this, and if it's not possible what can be done to give a similar result?


Edit: Using a function to both instantiate the class Neuron and saving it into a list within an instance of Brain seems the obvious answer. The problem occurs in the function Neuron.act() which instantiates the class Axon and must save it into a list that is in the same instance of Brain as used for the neuron. The previous constraints still apply.


Solution

  • class Brain(object):
        def __init__(self):
            self.neurons = []
            self.axons = []
    
        class Neuron(object):
            ...
    
        class Axon(object):
            ...
    
        def add_neuron(self, pos, AP_Energy, AP_threshold):
            self.neurons.append(Brain.Neuron(pos, AP_Energy, AP_threshold))
    
    
    EntityA = Brain()
    EntityA.add_neuron((0, 10), 15, 24)