Reputation: 827
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
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
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
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
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