Tony van der Hoff wrote: > Hi, > > I have a class A, containing embedded embedded classes, which need to > access methods from A. > . > A highly contrived example, where I'm setting up an outer class in a > Has-a relationship, containing a number of Actors. The inner class needs > to access a method of the outer class; here the method get_name. > > I don't really want to make Actor a sub-class (is-a; it isn't) of Monty; > that would raise all sorts of other problems. > > Can anyone please advise me on how to achieve this magic? > > # define the outer class > class Monty: > def __init__( self, names ): > self.actors = [] > > i = 0 > for n in names: > self.actors.append( Actor( n, i ) ) > i += 1 # here is a case for python supporting post-increment! > > def count_actors( self ): > return len( self.actors ) > > def list_actors( self ): > h=[] > for n in self.actors: > h.append( n.get_name() ) > return h > > # define the inner class > class Actor: > def __init__ ( self, name, id ): > self.name = name > self.id = id > > def get_name( self ): > > # and here lies the problem; > # AttributeError: Actor instance has no attribute 'count_actors' > # how do I access the method in the enclosing class > txt = "I'm Actor {} Number {} of {}".\ > format( self.name, self.id, self.count_actors() ) > > # this works, of course > #txt = "I'm Actor \"{}\"; Number {}. ".\ > format( self.name, self.id ) > > return txt > > if __name__ == '__main__': > o = Monty( ["Cleese", "Idle", "Palin" ] ) > print "number: ",o.count_actors() > a = o.list_actors() > for l in a: > print l > > Thanks, Tony
Ideally, you wouldn't. The Actor's name is independent of the number of them in the Monty, and all logic that needed to know about the full Monty would be there in list_actors, not delegated down to the Actor. That way all your dependencies are unidirectional: a Monty has a lot of expectations about an Actor but an Actor knows nothing about a Monty. And that's GREAT when you can make it work. Sometimes, in non-contrived examples, you get a situation where you can't avoid blending information around in both directions. In that case, your Monty instance is already acting as a factory for Actors. Keep going with that; have the Actor be init'ed with a .monty that refers back to the Monty containing it. It's a circular reference, but you can either a) break that using weakref or b) not care and trust Python's garbage collection to sort it all out eventually. -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix. -- https://mail.python.org/mailman/listinfo/python-list