Passing variable from one funtion to another
Question:
One thing I keep having trouble with in Python is passing information from one function to another, changing it and then passing it back to the original function to usefully use. Take a look at this very basic example, trying to create a ping function that can be called by various other functions.
import subprocess
pingchk = 0
def pinger(pcName, pingchk):
ping_out = subprocess.Popen(["ping", "-n", "1", pcName],stdout = subprocess.PIPE).communicate()[0]
if ('unreachable' in ping_out):
print "Warning", "PC not responding 1."
pingchk += 1
return pingchk
elif ('Request timed out.' in ping_out):
print "Warning", "PC not responding 2."
pingchk += 1
print pingchk
return pingchk
elif ('Ping request could not find host' in ping_out):
print "Warning", "PC not responding 3."
pingchk += 2
print pingchk
return pingchk
else:
print "Machine available!"
def someFunction():
pcName = raw_input("Please enter a pc name: ")
pinger(pcName, pingchk)
print pingchk
if pingchk == 1:
print "machine not switched on."
elif pingchk == 2:
print "machine name not recognized."
else:
print "success - machine on."
someFunction()
It’s the pingchk
bit that I’m struggling with. In this example someFunction
is passing the machineName
up to pinger
to do the work, then I want pinger
to pass the result back to someFunction
to use. However, someFunction
never re-reads the variable pingchk
so always reads it as 0
.
What do I need to change to pass the results of pinger
back to the originating function for use?
Answers:
To modify variables inside a function, pass them as list.
def ping(counter):
counter[0] += 1 # lists are passed by reference, hence they can be changed in place
mycounter = [0]
ping(mycounter)
print mycounter[0] # this will print 1
ping(mycounter)
print mycounter[0] # this will print 2
When you are calling a function in python, it returns a variable just like you are doing a basic math operation. For instance, if you do:
3*2
Your shell will return 6, but doesn’t save this result. If you want to save it, just do:
x = 3*2
The same goes for your function pinger
, when you call it from someFunction
, you have to do:
pingchk = pinger(pcName, pingchk)
As pingchk
otherwise is a local variable.
Another remark on your code: in someFunction
you first call pinger
with pingchk
as an argument but it doesn’t exist beforehand, therefore, your code won’t turn.
Two ways:
- Use a Global variable – Google will give you plenty of info and examples
-
My favorite, Put your variable in another module and import it.
e.g.
from commonstuff import pingcheck
As jonrsharpe suggested in a comment the way to go is simply to affect the returned value to the variable:
pingchk = pinger(pcName, pingchk)
There are only 2 caveats here:
-
you have a branch that does not return anything (when you print available) so you will end with a None which may not be what you expect: consistently return 0 in that case or better move the return out of the if:
def pinger(pcName, pingchk):
ping_out = subprocess.Popen(["ping", "-n", "1", pcName],stdout = subprocess.PIPE).communicate()[0]
if ('unreachable' in ping_out):
print "Warning", "PC not responding 1."
pingchk += 1
elif ...
else:
print "Machine available!"
return pingcheck
-
as you affect the variable pingcheck
in somefunction
before is has been used, Python consideres that it is a local variable hiding the global one. You must declare it as global – if you really need it to be global:
def someFunction():
global pingchk
pcName = raw_input("Please enter a pc name: ")
pingchk = pinger(pcName, pingchk)
But if you have no real reason for pingcheck to be global, just let it be local:
def someFunction():
pcName = raw_input("Please enter a pc name: ")
pingchk = pinger(pcName, 0)
One thing I keep having trouble with in Python is passing information from one function to another, changing it and then passing it back to the original function to usefully use. Take a look at this very basic example, trying to create a ping function that can be called by various other functions.
import subprocess
pingchk = 0
def pinger(pcName, pingchk):
ping_out = subprocess.Popen(["ping", "-n", "1", pcName],stdout = subprocess.PIPE).communicate()[0]
if ('unreachable' in ping_out):
print "Warning", "PC not responding 1."
pingchk += 1
return pingchk
elif ('Request timed out.' in ping_out):
print "Warning", "PC not responding 2."
pingchk += 1
print pingchk
return pingchk
elif ('Ping request could not find host' in ping_out):
print "Warning", "PC not responding 3."
pingchk += 2
print pingchk
return pingchk
else:
print "Machine available!"
def someFunction():
pcName = raw_input("Please enter a pc name: ")
pinger(pcName, pingchk)
print pingchk
if pingchk == 1:
print "machine not switched on."
elif pingchk == 2:
print "machine name not recognized."
else:
print "success - machine on."
someFunction()
It’s the pingchk
bit that I’m struggling with. In this example someFunction
is passing the machineName
up to pinger
to do the work, then I want pinger
to pass the result back to someFunction
to use. However, someFunction
never re-reads the variable pingchk
so always reads it as 0
.
What do I need to change to pass the results of pinger
back to the originating function for use?
To modify variables inside a function, pass them as list.
def ping(counter):
counter[0] += 1 # lists are passed by reference, hence they can be changed in place
mycounter = [0]
ping(mycounter)
print mycounter[0] # this will print 1
ping(mycounter)
print mycounter[0] # this will print 2
When you are calling a function in python, it returns a variable just like you are doing a basic math operation. For instance, if you do:
3*2
Your shell will return 6, but doesn’t save this result. If you want to save it, just do:
x = 3*2
The same goes for your function pinger
, when you call it from someFunction
, you have to do:
pingchk = pinger(pcName, pingchk)
As pingchk
otherwise is a local variable.
Another remark on your code: in someFunction
you first call pinger
with pingchk
as an argument but it doesn’t exist beforehand, therefore, your code won’t turn.
Two ways:
- Use a Global variable – Google will give you plenty of info and examples
-
My favorite, Put your variable in another module and import it.
e.g.from commonstuff import pingcheck
As jonrsharpe suggested in a comment the way to go is simply to affect the returned value to the variable:
pingchk = pinger(pcName, pingchk)
There are only 2 caveats here:
-
you have a branch that does not return anything (when you print available) so you will end with a None which may not be what you expect: consistently return 0 in that case or better move the return out of the if:
def pinger(pcName, pingchk): ping_out = subprocess.Popen(["ping", "-n", "1", pcName],stdout = subprocess.PIPE).communicate()[0] if ('unreachable' in ping_out): print "Warning", "PC not responding 1." pingchk += 1 elif ... else: print "Machine available!" return pingcheck
-
as you affect the variable
pingcheck
insomefunction
before is has been used, Python consideres that it is a local variable hiding the global one. You must declare it as global – if you really need it to be global:def someFunction(): global pingchk pcName = raw_input("Please enter a pc name: ") pingchk = pinger(pcName, pingchk)
But if you have no real reason for pingcheck to be global, just let it be local:
def someFunction():
pcName = raw_input("Please enter a pc name: ")
pingchk = pinger(pcName, 0)