Passing Variables between Defs

382
2
07-17-2019 12:19 PM
JoeBorgione
MVP Emeritus

Global variables seem to draw the scorn if not ire of most python developers, and recently I've been faced with a situation where creating a variable in a series of defs needs to be passed back to  main().  I did a little searching with my friend and associate Dr. Google and found a stack over flow thread which gave me an idea. 

In the script I'm (re) writing, I'd like to follow the form of defining my defs() and then calling them from main().  However, each of my defs() use a try/except block, and if there is an exception anywhere along the line I need to abort the final processing.

This is what I came up with in concept:

errorList = []
def first():
    try:
        #some code
    except:
        errorList.append(1)

def second():
    try:
        #some other code
    except:
        errorList.append(1)
    
def main():
    first()
    second()
    if len(errorList) == 0:
        # final operations
    else:
        # don't execute final operations    
    
main()

Pretty simple concept right?

Taking it one step further, I started thinking how about this:

def1List = []
def2List = []

def one():
    #blah,blah
    append def1List(someValueFromBlah)
    append def1List(anotherValueFromBlah)

def two():
    # blah2 blah2
    append def2List(someValueFromBlah2)
    append def2List(anotherValueFromBlah2)
    
def three():
    if def1List[0] == myTargetValue:
        do something
    elif defList[1] == myOtherTargetValue:
        do something else...
    myValue = def2List[0]
    myOtherValue = def2List[1]
    # use myValue and MyOtherValue as I need to...‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

These look like they'll work for me in a number of different applications, but I'd like to here from you (and you know who you are) as to whether or not these are:

Good Practice

Bad Practice

Something everybody does already

Etc

Etc....

That should just about do it....
0 Kudos
2 Replies
DanPatterson_Retired
MVP Emeritus

each def could use a return which could be checked to bypass any failures.  Although I don't recommend 'chaining' as in the pattern below... but hopefully you get the drift.

 def first(a):
    """ """
    if not isinstance(a, (int, float)):
        return False
    return a*2
    
def second(b):
    """ """
    if not isinstance(b, (int, float)):
        return False
    return b + 2
    
def third(c):
    """ """
    if not isinstance(c, (int, float)):
        return "totally blew it"
    return "{} ta dahhhh".format(c)
    
def may_nhh(val):
    """ """
    back = first(val)
    if not back:
        return "bailed on a"
    again = second(back)
    if not again:
        return "bailed on b"
    finallement = third(again)
    return finallement
    

may_nhh(5)
'12 ta dahhhh'

may_nhh('a')
'bailed on a'
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Unless you are cleaning something up after the error in your defs, why not let the error get raised in the def and then capture it in main from a try/except there:

def first():
        #some code

def second():
        #some other code
    
def main():
    funcs = first, second
    for func in funcs:
        try:
            func()
        except:
            # don't execute final operations
    
    # final operations
    
main()
0 Kudos