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?

Asked By: user3514446

||

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
Answered By: user1308345

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.

Answered By: ysearka

Two ways:

  1. Use a Global variable – Google will give you plenty of info and examples
  2. My favorite, Put your variable in another module and import it.
    e.g.

    from commonstuff import pingcheck

Answered By: Bill M

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)
Answered By: Serge Ballesta
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.