Mike Vella
Mike Vella

Reputation: 10575

Call an arbitrary child attribute from a parent class?

I want to 'mark' attributes of a derived class (which are otherwise identical) so that a method of the parent class can use a specific one.

In this example I am building models of neurons, each neuron consists of "regions" which in turn consist of "segments". There is a neuron_region parent class. The neuron_region parent class has a "connect" method which connects a segment to another segment (passed to it as an argument - on another neuron). There needs to be a way of marking which segment in the derived class needs to be connected to. What is an elegant way to do this?

class neuron_region(object):
    def connect(external_segment)
       #connect segment 1 or segment 2 to external_segment, 
       #depending on which one is the right attribute

class child1(parent):
    #mark segment 1 as the segment to which to connect#
    self.seg1='segment 1'
    self.seg2='segment 2'

class child2(parent):
    self.seg1='segment 1'
    #mark segment 2 as the segment to which to connect#
    self.seg2='segment 2'

Upvotes: 0

Views: 875

Answers (2)

glglgl
glglgl

Reputation: 91017

You could do

class neuron_region(object):
    def connect(external_segment)
       #connect segment 1 or segment 2 to external_segment, 
       #depending on which one is the right attribute
    # the following can/must be omitted if we don't use the conn_attr approach
    @property
    def connected(self):
        return getattr(self, self.conn_attr)

class child1(parent):
    seg1 = 'segment 1'
    seg2 = 'segment 2'
    #mark segment 1 as the segment to which to connect#
    conn_attr = 'seg1'
    # or directly - won't work if seg1 is changed sometimes...
    connected = seg1


class child2(parent):
    seg1 = 'segment 1'
    seg2 = 'segment 2'
    #mark segment 2 as the segment to which to connect#
    conn_attr = 'seg2'
    # or directly - won't work if seg2 is changed sometimes...
    connected = seg2

Here you have even 2 approaches:

  1. The child class defines a conn_attr attribute to determine which attribute is the one to use for connecting. It is used in the connected property in the base class. If seg1 resp. seg2 changes from time to time, this is the way to go.

  2. The child class directly defines connected. Thus, no need for a redirecting property, but that works only if none of the used attributes changes.

In both approaches, the parent class just uses self.connected.

Upvotes: 0

pillmuncher
pillmuncher

Reputation: 10162

Do The Simplest Thing That Could Possibly Work - maybe something along the lines of:

SEGMENTS = (SEGMENT_1, SEGMENT_2) = range(2)

class NeuronRegion(object):
    def __init__(self):
        self.connection = [None, None]
        self.chosen = 0
    def choose(self, segment):
        assert segment in SEGMENTS
        self.chosen = segment
    def connect(other_neuron_region):
       # remember to reset those to None when they're not needed anymore, 
       # to avoid cycles that prevent the garbage collector from doing his job:
       self.connection[self.chosen] = other_neuron_region
       other_neuron_region.connection[other_neuron_region.chosen] = self

class Child1(NeuronRegion):
   ''' other stuff '''

class Child2(NeuronRegion):
   ''' other stuff '''

[EDIT] I have to admit that I don't like this very much, but it does what you asked for, IMO.

Upvotes: 1

Related Questions