开发者

Python: Why Does a Method Behave Differently with an Added Parameter?

I have a method in a Pygame Sprite subclass, defined as such:

def walk(self):
    """move across screen"""
    displacement = self.rect.move((self.move, 0))
    if self.rect.left < self.area.left or self.rect.right > self.area.right:
        self.move = -self.move
        displacement = self.rect.move((self.move, 0))
    self.rect = displacement

I modified it, adding a parameter speed_x, and now the program is broken.

def walk(self, speed_x):
    """move across screen"""
    displacement = self.rect.move((speed_x, 0))
    if self.rect.left < self.area.left or self.rect.right > self.area.right:
        speed_x = -speed_x
        displacement = self.rect.move((speed_x, 0))
    self.rect = displacement

Before I called the method like this:

def update(self):
        self.walk()

Now I do:

def update(self):
    开发者_如何学Cself.walk(self.move)

Why doesn't this work?


You don't explain how it's "broken", but the main difference is that

speed_x = -speed_x

which you have in your second version, is only changing the local variable (arguments are local variables!) speed_x, so that changed value does not persist.

In the first version,

self.move = -self.move 

does alter self (specifically one of its attriubtes) and the alteration "persists" in future method calls on the object which is here accessed as self.

Just one of the many key differences between bare names (like speed_x) and qualified names (line self.move), and, I suspect, what's biting you here (hard as you may make it to guess by not saying how the second version is failing your expectations).


You are no storing the offset back in to self.move.


If you want to use the second version of your code, try adding this line:

    self.move = speed_x

At the bottom of your function.


As mentioned by others, you are not changing the value of self.move in your new code. I assume the reason you modified this function was so you could reuse this function for values other than self.move.

If you want to be able to pass different arguments into your function and modify them as well, you could pass the modified value of speed_x back as a return value:

def walk(self, speed_x):
    """move across screen"""
    displacement = self.rect.move((speed_x, 0))
    if self.rect.left < self.area.left or self.rect.right > self.area.right:
        speed_x = -speed_x
        displacement = self.rect.move((speed_x, 0))
    self.rect = displacement
    return speed_x

And call the function like this as:

def update(self):
    self.move = self.walk(self.move)

Note: This answer assumes that self.move should not always be updated when calling walk. If this assumption is false and self.move should in fact be updated every time walk is run, then you should instead use Xavier Ho's answer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜