Jump to content
  • Advertisement
Sign in to follow this  
Splinter of Chaos

Python: How do you return multiple variables from a function

This topic is 4340 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to creat a parser because after about two weeks of programming, surprisingly it seems I'm ready. But I've encountered two problems, the first has been solved independantly, but the second revolves around my use of the return statement and the nessesity of returning more that one item. I made two different versions, both have the same problem. Here's the first and original:
def get_input(): # Tested. Works.
    """Demands input.

    Asks for input and makes sure there was infact input."""
    global act
    while len(act) == 0:
        act = raw_input("What would you like to do?\n")
        if len(act) < 0:
            print "No command has been given. Please try again."
            return
        else:
            actOld = act
            act = act.lower()
            actList = act.rsplit()
            
    # [02 BUG] Only the first variable is returned.
    # <2006-07-07>
    return act ,actOld ,actList
The "[02 BUG]" is just how I document my bugs errors and stuff, (before the code actually starts I have an index of bugs, things needing doing, etc etc. And the problem is proclaimed in the code. Here's the second.
def get_input():
    """Demands input.

    Asks for input and makes sure there was infact input."""
    global act
    while len(act) == 0:
        act = raw_input("What would you like to do?\n")
        if len(act) < 0:
            print "No command has been given. Please try again."
            return
        else:
            actOld = act
            act = act.lower()
            actList = act.rsplit()
            
            # The return statement only workd for one var so a list was made.
            # act = 0; actOld = 1; actList = 2
            goal = [act, actOld, actList]
            
    # [02 BUG] The list is not returned AT ALL!
    # <2006-07-07>
    return goal
I thought that by putting in a list instead of a normal variable it would carry through, but it made it worse, as I said in the code, the list wasn't returned at all!

Share this post


Link to post
Share on other sites
Advertisement
How are you calling those functions? Both forms of return are fine. My guess is that perhaps something else is going wrong.

Share this post


Link to post
Share on other sites
This works just fine:

def foo():
return 1, 2, 3

x, y, z = foo()

Both versions of your get_input() function look like they have a couple of bugs. First, the str object does not have an rsplit() method, so an AttributeError exception will be raised at this point in the code.

Secondly, where is 'act' cleared? If it's not being cleared outside of this function and guaranteed to be cleared between calls, the while loop will cause control to flow directly to the return. Since you're trying to save the old value of act when you get new input, it looks like you're assuming act is not cleared. You need to review this logic and make it consistent.

Share this post


Link to post
Share on other sites
Quote:
Original post by kinetik_mjg

Both versions of your get_input() function look like they have a couple of bugs. First, the str object does not have an rsplit() method, so an AttributeError exception will be raised at this point in the code.


??? Do you mean the act that I want lowercase should be this?
[soource lang="python"] act = act.rsplit().lower()[/source]
If not, be be more specific or more lamen, but my guess is on more specific.

And as for "where is act cleared?"
I your asking where I delet the variable for later use so it doesn't mess up my code. In that case, I clear it when I'm done using it. I wouldn't clear it until I've processed the input and responded would I? But again, if I'm not understanding your question, be more specific or more lamens.

(Note: I don't ask that you be more lamens (that is if I don't understand you, otherwise it's good,) because I don't want to learn the terms, but because I still have to learn them.

EDIT:
Quote:
Original post by Kylotan
How are you calling those functions? Both forms of return are fine. My guess is that perhaps something else is going wrong.


Hm. Well, the main block looks like this.
for x in range(1,2):
get_input()
print goal
if act:
process_input(act)


Although I've changed it thanks to kinetik_mjg's advice to this:
for x in range(1,2):
act ,actOld ,actList = get_input()
# Test print, WORKS
print act, actList, actOld
if act:
process_input(act)



[Edited by - Splinter of Chaos on July 8, 2006 4:32:57 PM]

Share this post


Link to post
Share on other sites
Oops, ignore my remark about rsplit()--I see that it's new in Python 2.4.

As for clearing act, I'll demonstrate with code:

act = ""

def get_input():
global act

# this test will be false if act has not been cleared and the code
# will try to return actOld and actList, which are only set in the else
while len(act) == 0:
act = raw_input("What would you like to do?\n")

# this test will never be true, so code always goes into else part
if len(act) < 0:
print "No command has been given. Please try again."
return
else:
actOld = act
act = act.lower()
actList = act.rsplit()
return act, actOld, actList

# works first time
x, y, z = get_input()
print "act='%s', x='%s', y='%s', z='%s'" % (act, x, y, z)

# but not this time (UnboundLocalError: local variable 'actOld' referenced before assignment)
x, y, z = get_input()
print "act='%s', x='%s', y='%s', z='%s'" % (act, x, y, z)

# so we need to clear act first, and then it works
act = ""
x, y, z = get_input()
print "act='%s', x='%s', y='%s', z='%s'" % (act, x, y, z)



I assume that in your case, your process_input() function is responsible for clearing act?

So, returning multiple values works as expected, but the code is broken if act has not been cleared before it is called again. This should be fixed up. The len(act) < 0 test is also broken and needs to be fixed (maybe len(act) == 0?). I would strongly recommend changing the code so that it does not rely on act being global--use of global variables makes code very fragile.

Share this post


Link to post
Share on other sites
Okay . . . but then how do I use act then? I have about three (thus far) different functions that all require the use of act, do you sugest I call get_input() for each one?

And lastly, what is the rsplit()? I do have Python 2.4, do I use it or don't?

EDIT:
The Python documentation said
Quote:
rsplit( [sep [,maxsplit]])
Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. New in version 2.4.


Sounds like I don't really need this because I can keep the string a string and still parse fine. I see no disadvantages, but also no advantages for using rsplit().

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!