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.
精彩评论