Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Erik Newsgroups: comp.lang.python Subject: Re: Accessing container's methods Date: Mon, 7 Dec 2015 23:47:26 +0000 Lines: 78 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de jk8xswEmvCcp8VOlP+5t2QlhNFX3FXVHOmsbh243AphQ== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'modified': 0.05; 'differently': 0.07; 'nasty': 0.07; '__init__': 0.09; 'implies': 0.09; 'python': 0.10; 'assume': 0.11; 'def': 0.13; '"key"': 0.16; 'class;': 0.16; 'containers': 0.16; 'contrived': 0.16; 'from:addr:python': 0.16; 'iterators,': 0.16; 'itertools': 0.16; 'list)': 0.16; 'organised': 0.16; 'parent):': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'sfxlen:0': 0.16; 'sorting': 0.16; 'subject:Accessing': 0.16; 'sync': 0.16; 'wrote:': 0.16; 'circular': 0.18; '(in': 0.18; 'first,': 0.20; 'to:2**1': 0.21; '(the': 0.22; 'txt': 0.22; 'pass': 0.22; 'trying': 0.22; '(you': 0.23; 'comment:': 0.23; 'references': 0.23; 'import': 0.24; 'header:In-Reply-To:1': 0.24; 'module': 0.25; 'header:User- Agent:1': 0.26; 'example': 0.26; 'van': 0.26; 'skip:" 20': 0.26; 'bugs': 0.27; '(such': 0.27; "skip:' 10": 0.28; 'container': 0.29; "i'm": 0.30; 'print': 0.30; 'creating': 0.30; 'anyone': 0.32; 'another': 0.32; "can't": 0.32; 'statement': 0.32; 'class': 0.33; "i'll": 0.33; 'add': 0.34; 'list': 0.34; 'quite': 0.35; 'asking': 0.35; 'too': 0.36; 'skip:i 20': 0.36; 'should': 0.36; 'possible': 0.36; 'alone': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'method': 0.37; 'setting': 0.37; 'wanted': 0.37; 'things': 0.38; 'version': 0.38; 'names': 0.38; 'self': 0.38; 'or,': 0.38; 'received:192': 0.39; 'to:addr:python.org': 0.40; 'where': 0.40; 'your': 0.60; 'total': 0.62; 'charset:windows-1252': 0.62; 'more': 0.63; 'here': 0.66; '"index"': 0.84; '(let': 0.84; 'container).': 0.84; 'amongst': 0.91; 'sensibly': 0.91 X-CM-Score: 0.00 X-CNFS-Analysis: v=2.1 cv=LpJvsSpc c=1 sm=1 tr=0 a=Ypmeq7T0cKALDUsRPCToMg==:117 a=Ypmeq7T0cKALDUsRPCToMg==:17 a=0Bzu9jTXAAAA:8 a=EBOSESyhAAAA:8 a=N659UExz7-8A:10 a=lzT82s0P8M_A6Qas1xEA:9 a=1LX_NEdhlW4wJGLm:21 a=KACfK9cfYHam7hTH:21 a=pILNOxqGKmIA:10 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 In-Reply-To: X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:100120 Hi Tony, On 07/12/15 18:10, Tony van der Hoff wrote: > 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. Generally, an object should not need to know which container it's in (let alone its "index" or "key" in that container). Amongst other things, you can't put the object into multiple containers which might be organised differently and you are asking for bugs where the container and the object get out of sync WRT just where the object is in the container (in your example, if you found you wanted to add a method where the 'actors' list is modified (say, calling "self.actors.insert(3, ...)", or sorting the list) then things get nasty quickly. However, you've said this is a highly contrived example, so I'll bear with you and assume what you're trying to do is not quite as nasty as the example implies ;) > Can anyone please advise me on how to achieve this magic? As you can't sensibly put the object into more than one container at a time anyway, then you can pass the container object to the Actor object as its "parent". It can then call its parent object for things that the parent will know (such as, the total number of contained objects): class Actor: def __init__ ( self, name, id, parent ): self.name = name self.id = id self.parent = parent def get_name( self ): txt = "I'm Actor {} Number {} of {}".\ format( self.name, self.id, self.parent.count_actors() ) return txt Then you can add a new actor with: self.actors.append( Actor( n, i, self ) ) Note that you are creating circular references here, too (the container references the Actor object and the Actor object references the container). Just another possible issue to bear in mind ... Also, while I'm looking at this, you have this loop and comment: > 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! However, if you refactor that loop to use iterators, you don't need to manually manipulate 'i' at all (you need to import the itertools module first, and this is the "new" version where the container is passed in as the parent): def __init__( self, names ): self.actors = [ Actor ( n, i, self ) for n, i in itertools.izip(names, itertools.count()) ] Or, if you don't like list comprehensions: def __init__( self, names ): self.actors = [] for n, i in itertools.izip(names, itertools.count()): self.actors.append( Actor( n, i, self ) ) (I assume you're using Python 3 because of your print statement - in Python 3, 'itertools.izip' should just be 'zip'.) HTH, E.