I stumbled on upon this anomaly in one of my programs and can't figure out why this is happening. I made a small test function that exhibits the same behavoir. It's like the local variables of my function are being saved after the function exits. The exclude_ids variable keeps growing. This same behavoir is apparent in IDLE, from cmd line, and when compiled. Tested on windows XP & 8. Python 2.7.4

>>> def is_running(exe_name, by_path=False, exclude_ids=[], exclude_this_process=False):
    from os import getpid
    from os.path import basename, abspath
    if exclude_this_process:
        exclude_ids.append(getpid())
    print "exluded ids %s" % exclude_ids
    return "-----------------"

>>> for x in xrange(10):
    is_running("bob.exe", exclude_this_process=True)


exluded ids [5584]
'-----------------'
exluded ids [5584, 5584]
'-----------------'
exluded ids [5584, 5584, 5584]
'-----------------'
exluded ids [5584, 5584, 5584, 5584]
'-----------------'
exluded ids [5584, 5584, 5584, 5584, 5584]
'-----------------'
exluded ids [5584, 5584, 5584, 5584, 5584, 5584]
'-----------------'
exluded ids [5584, 5584, 5584, 5584, 5584, 5584, 5584]
'-----------------'
exluded ids [5584, 5584, 5584, 5584, 5584, 5584, 5584, 5584]
'-----------------'
exluded ids [5584, 5584, 5584, 5584, 5584, 5584, 5584, 5584, 5584]
'-----------------'
exluded ids [5584, 5584, 5584, 5584, 5584, 5584, 5584, 5584, 5584, 5584]
'-----------------'
>>> 

The list just keeps growing....

Recommended Answers

All 6 Replies

Ok from what I see you never test to see if the process ID is in your list of ID's to exclude. I think you need another test to see if the id is in the array of Process ID's. My guess is that the test should be done around line 4 or 5 to check it the id supplied s already in the list of excluded ids.
Hope that makes sense...

K, those are good convention tips, but why is this happening?

Tony pointed me in the right direction. My old understanding of default parameters was that they were set each time the function was called. It appears however that each call to the function actually mutates the function object, meaning that if a mutatble object is changed that change is permanent. Heres some helpful answers
http://stackoverflow.com/questions/366422/what-is-the-pythonic-way-to-avoid-default-parameters-that-are-empty-lists

Now I get to rewrite most of my python programs.

I have once watched a great pycon video about the python execution process. Sadly I cannot find any written words about that.

In my understanding it works as follows:

  • The python interpreter "executes" from the first line of the script.
  • This execution involves compilation and evaluation. Evaluation is evaluating expressions and labelling it with names, in other words getting memory, creating objects, calculation, namespace changes. Compilation is compiling the statements to byte code for later evaluation, if it is not already compiled. Evaluation includes compilation.
  • All imported files are executed, the difference between the import styles is in where to find the files and where to put the names.
  • If a def statement is encountered, then execution means the followings: The function name is placed into the appropriate namespace. The default arguments are evaluated and bound to the function, and after that the function body is compiled and bound to the function name, too.
  • If a function call - without overwriting the default argument- is encountered, then the execution takes the default argument from the function, and executes the precompiled function body.

So if you use a default argument for a function, then this object remains the same during the session. If this object is mutable (like a list or a set), then you will encounter the above problems.

def is_running(exe_name, by_path=False, exclude_ids=(), exclude_this_process=False):
    from os import getpid                      #change here
    from os.path import basename, abspath
    if exclude_this_process:
        exclude_ids.append(getpid())
    print "exluded ids %s" % exclude_ids
    return "-----------------"

It will add to a mutable object

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.