Hum, sorry about the empty reply; just finger trouble!

Anyway I wasn't expecting such a great response; thanks to all.

On 07/12/15 23:47, Erik wrote:
[snip]

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 ) )

Whilst I'm grateful for all the responses, this is the one that got me out of the hole I dug myself into.

In fact, this is precisely what I tried previously, and got:
TypeError: 'instancemethod' object has no attribute '__getitem__'

In my naivety, I concluded that this meant I couldn't use the 'self' pointer in this way. However, trying it with the Monty example, it worked fine, and I have now tracked down my error elsewhere.


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 ...

Yes, I guess it's quite nasty, but, in the non-trivial case, I'm only calling for dynamic data from the parent, and not modifying it in any way, so I think I can get away with it. Otherwise, I'd have to pass a vast list of initialization data to the (many) children, and keep that up to date by passing it down the line to each one, just in case it's required, which would slow down things excessively. I know that if a design doesn't feel comfortable, then it's probably wrong, but I believe that in this case it's probably the best way forward.


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 rather liked Terry's suggestion of using enumerate.

The comment was tounge-in-cheek: Referring to an earlier thread, I'm yet to be convinced that Python is better for not having pre/post-increment/decrement operators. But, hey, I'm sure better minds than mine have addressed the subject ;)

(I assume you're using Python 3 because of your print statement - in
Python 3, 'itertools.izip' should just be 'zip'.)

No, Im actually stuck on Python 2.7. I don't see how you jumped to that conclusion from a simple print statement.

On 07/12/15 21:38, Terry Reedy wrote:
[snip]
> This is actually a case for using enumerate:
>    for i, name in enumerate(names):
>
I've not come across this previously, but shall certainly use it in future. Thanks!

> return list(self.actors)  # or perhaps even faster
> return self.actors[:]

That doesn't seem to work:
<__main__.Actor instance at 0x7fc7478ba560>
<__main__.Actor instance at 0x7fc7478ba5a8>
<__main__.Actor instance at 0x7fc7478ba5f0>


Anyway, I'm no longer in a hole; thanks for all the excellent help. I'll certainly review the design of my current project, to see if it can be improved.

Cheers, Tony

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to