简体   繁体   中英

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):
    self.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).

您无需将偏移量存储回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.

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