简体   繁体   中英

Python: Why would a function called within a while loop return something different than when called alone?

I have a first function, move(x, y, u, v) that is used to move a piece from coordinates (x,y) to (u, v) in a board game.

some_Class():
    def move(self, x, y, u, v):

        self.x = x
        self.y = y
        self.u = u
        self.v = v

        if (conditions for possible move...):
            return(some_function(self.x, self.y, self.u, self.v)) ## applies the move

        else:
            return("Move impossible. Try again.")

When the move is possible, the function moves the piece on the board and when the move is not possible, it returns a string that says "Move impossible".

I have a lot of testing to do, so to simplify my life I made a seconde function:

def play()
    a = input()
    b = []
    for i in a:
        b.append(i)
    return(move(b[0], b[1], b[2], b[3]))

and I put it in an infinite loop so I can keep trying move after move.

while True:
    play()

The whole thing is working properly, the pieces are moved according to the rules of the game and everything is fine except that when the move is impossible I don't get the "Move impossible" message.

If I call play() by itself (outside of the while loop, in the shell for example), and attempt an impossible move, I do get the message.

I'm pretty sure this is something very basic but I couldn't find the answer anywhere and I need these messages because I use them to locate errors in the code.

I'll add an example in case it is not clear. Let's say move from (0,0) to (1,1) is impossible.

Case 1, play() without the loop:

>>>play()
0011
'Move impossible. Try again.'

Case 2, play() inside a loop:

while True:
    play()

0011

0011

...

The move is not played (the piece stays in its place), but I don't get the message. Why is that?

EDIT: Problem solved.

print(play())

didn't work, but all I had to do was

return(print("Impossible move"))

instead of

return("Impossible move")

Thank you everyone for the help :)

Your function returns a string. When you call it from the interpreter, it gets printed automatically since it's the result of the statement you're running, but if it's inside a while loop you'll need to print it explicitly for it to show up. The string is being returned, but you're not doing anything with the return value.

Try this:

while True:
    print(play())

Incidentally, this is one of the reasons why returning errors in the same manner as valid results can be a problem. It'd be better to raise an exception when there's an invalid move, and then using a try/except to handle the error case.

For example:

# (in move):
if valid_move(...):
    return(do_move(...))
else:
    raise ValueError("Move impossible, try again")

# (in play):
try:
    move(...)
except ValueError as err:
    print(err)

When you run play() at the interactive prompt, Python prints the value of the expression (its return value).

Inside the loop, this doesn't necessarily happen. You don't do anything with the expression, so the value is thrown away. (With the base Python REPL, it does actually print out bare values inside a loop; but IPython, for example, does not.)

So, if you want to see the result, use print(play()) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM