[Tutor] How python keeps track of objects

Dave Angel davea at davea.name
Sun Nov 23 17:07:27 CET 2014

Please don't top-post.  Trim the quoted portion to the parts you're 
responding to, and put your response immediately after (each) section 
you're commenting on.

Also, you're posting in html.  That's not always a problem, but it often 
is, depending on the vagaries of your email program.  Just tell it you 
want text format for your messages here, and we'll all see the same thing.

On 11/23/2014 10:15 AM, Mitch Raful wrote:
> Thanks for the replies.   My concern was as the for loop keeps sending
> objects into the do_something() function which uses the same reference name
> other_object and that the previously instantiated other_objected would be
> mutated if the function wasn't finished.

I can't process that.  I don't know what you're asking.

> Or do all languages keep each
> call to a function in its own memory space and there is not a collision?.

No such statement for "all languages," as there are tens of thousands of 
them, at least.  And certainly there are some that support implicit 
concurrency via something like  "for all" meaning "you may do all of 
these in parallel if you like, and I promise that order doesn't matter".

In Python, however, the function as you had it in the original message 
returns to the for loop before it gets called again.  So there's only 
one instance of the stack frame.

Three ways there can be multiple stack frames for the same function:

1) the function calls itself, directly or indirectly
2) you have multithreading
3) you have multiprocessing

In all of these cases, the name other_object is unambiguously replicated 
in each instance of the stack frame.  And each version of that can be 
bound to an independent object.

> Since, in my case, do_something() actually occurs over a network and I use
> the logging module, I noticed the responses come in whatever order they
> have completed and not the order that do_something is called.

Then you are not just doing a simple function call.  You're doing some 
form of asynchronous I/O, either by threading, or by non-blocking I/O. 
In either case, your original example doesn't begin to represent what 
you're doing.

The "responses come in" imply that somewhere you're polling for those 
responses.  Or you've changed your code to use multiple threads (as you 
show below).

> I also have
> another function that downloads the resulting files on the devices that
> do_something() has them generate.   To get all of this to look orderly in a
> log output, I did this...
> for object in objects:
>      t0 = Thread( target=do_something, args=(object,))
>      t0.start()
>      t1 = Thread( target=get_files, args=(object, backup_dir))
>     t1.start()
> As to whether I read this somewhere, I wish I could blame a publication.
> Alas, I came up with 'beauty' on my own.

Once you launch a second thread, you have to worry about when it's done 
updating the corresponding item in objects.  So somewhere you probably 
want a wait() call.

Anyway, the need for threads is triggered by my point 1), a need to 
continue your loop without waiting for the first operation to complete. 
  It doesn't happen to be the user interface that's causing it, but the 
network.  You've decided that you want to start multiple network 
operations without waiting for the first to complete.  That's easiest 
done with threads.


More information about the Tutor mailing list