user2113818
user2113818

Reputation: 827

Python: passing values from function to function

I've been fighting with this for three hours now.

ETA- Should have mentioned this, but for purposes of this class, not allowed to use global variables.

Within function main(), I want to run a function firstPass if and only if it's the first time the whole function is being run. The firstPass function initializes a couple variables and prints some information that is not interesting if it's not the first time you see it.

I duly have:

#Initialize variables that need to run before we can do any work here
count = 0

def firstPass():
    x = 5
    y = 2
    print "Some stuff"
    count = count + 1
    print "Count in firstPass is",count
    return count,x,y

def main ():
    print "Count in main is",count
    if count == 0:
        firstPass()
    else:
        #Do a whole bunch of other stuff that is NOT supposed to happen on run #1
        #because the other stuff uses user-modified x and y values, and resetting
        #to start value would just be self-defeating.

main()

This returns correctly on the first pass, but on subsequent passes, returns:

Count in main is 1

This is also a problem for my user-modified x and y values within other functions. Though I haven't modified them here, I did include them because I need to pass multiple values between functions later on in the code, but who wants to read all that when I could just put them here for the sake of the example...

I was under the impression that

return [variable]

passed the CURRENT (i.e. whatever that variable became within the current function) value of the variable back to other subsequent functions. Either my understanding is wrong, or I am just doing it wrong.

Upvotes: 1

Views: 4038

Answers (4)

Rushy Panchal
Rushy Panchal

Reputation: 17532

def firstPass(count):
    x = 5
    y = 2
    print "Some stuff"
    count = count + 1
    print "Count in firstPass is",count
    return count,x,y

def main():
    count = 0 # initialize it here; you're only running main once
    print "Count in main is",count
    if count == 0:
        count, x, y = firstPass(count) # sets the values from firstPass()
    else:
        #Do a whole bunch of other stuff that is NOT supposed to happen on run #1
        #because the other stuff uses user-modified x and y values, and resetting
        #to start value would just be self-defeating.

main()

However, if you want to initialize count outside of main(), use main(count):

#Initialize variables that need to run before we can do any work here
count = 0

def firstPass(count):
    x = 5
    y = 2
    print "Some stuff"
    count = count + 1
    print "Count in firstPass is",count
    return count,x,y

def main (count):
    print "Count in main is",count
    if count == 0:
        firstPass()
    else:
        #Do a whole bunch of other stuff that is NOT supposed to happen on run #1
        #because the other stuff uses user-modified x and y values, and resetting
        #to start value would just be self-defeating.

main(count) # pass it as an argument

However, if you are only calling main() once, you can rewrite your code and general structure like this:

def main():
    count = 0
    count, x, y = firstPass(count) # no need to check if it is 0
    # do everything else

def firstPass(count):
    x, y = 5, 2 # multiple assignment, same as x = 5; y = 2
    print "some stuff"
    count += 1 # shorthand for count = count + 1
    print "Count in firstpass is", count
    return count, x, y

main()

Upvotes: 0

Mark Ransom
Mark Ransom

Reputation: 308176

Your understanding of return is wrong.

The values returned aren't just inserted back into the namespace of the caller, they have to be received. They don't have to be received with the same name either.

count,a,b = firstPass()

Also I'd suggest passing the current count into the function as a parameter, rather than grabbing it from a global. It's just better style all around, and makes your functions easier to understand.

Upvotes: 2

user849425
user849425

Reputation:

You need to do:

def firstPass():
    global count

to get the count variable to update.

By using the global keyword you tell the interpreter to load and store the value into the global count variable instead of saving it to a local variable of the same name. For example:

I define two functions, one with and one without using global:

>>> a = 0
>>> def foo():
...   a += 1
...   return a
>>> def bar():
...   global a
...   a += 1
...   return a

After disassembling both functions using the dis module, it becomes apparent what the difference is:

>>> import dis
>>> dis.dis(foo)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_CONST               1 (1)
              6 INPLACE_ADD         
              7 STORE_FAST               0 (a)

  3          10 LOAD_FAST                0 (a)
             13 RETURN_VALUE        

>>> dis.dis(bar)
  3           0 LOAD_GLOBAL              0 (a)
              3 LOAD_CONST               1 (1)
              6 INPLACE_ADD         
              7 STORE_GLOBAL             0 (a)

  4          10 LOAD_GLOBAL              0 (a)
             13 RETURN_VALUE        

Upvotes: 2

monkut
monkut

Reputation: 43830

You probably want to consider using a class. It's a better container for maintaining state.

def firstPass():
    x = 5
    y = 2
    print "Some stuff"
    count = count + 1
    print "Count in firstPass is",count
    return count,x,y        

class MyActivityManager(object):
    def __init__(self):
        """Initialize instance variables"""
        self.run_count = 0

    def run(self):
        if not self.run_count:
            results = firstPass()
            self.run_count += 1
            # consider saving results in the instance for later use
        else:
            # other stuff


if __name__ == "__main__":
    runner = MyActivityManager()
    runner.run()

Upvotes: 0

Related Questions