在Python中访问其他类的函数

2 投票
3 回答
1610 浏览
提问于 2025-04-17 00:02

我刚开始学Python,所以对我这个问题感到抱歉,肯定是个很明显的问题。我想让类 Computer_paddle 能够调用 Ball 的函数 y_position(),并获取返回值。但是它似乎没有做到这一点,告诉我:

"global name 'ball' is not defined". 

我需要做些什么特别的事情才能在一个函数里调用另一个函数吗?

class Ball(games.Sprite):
    """ A ball that bounces off walls and paddles. """
    image = games.load_image("ball.png")

    def __init__(self, game, x, y):
        """ Initialise ball sprite. """
        super(Ball, self).__init__(image = Ball.image,
                                   x = x, y = y,
                                   dx = -3, dy = 0)

    def update(self):
        """Check if ball has hit paddle or wall, and then bounce that ball. """
        super(Ball, self).update()

        # check if ball overlaps paddles
        if self.overlapping_sprites:
            self.dx = -self.dx
            self.dy += random.randint(-1, 1)

        # check if ball hits a wall
        if self.top < 0 or self.bottom > games.screen.height:
            self.dy = -self.dy
        if self.left < 0 or self.right > games.screen.width:
            self.dx = -self.dx

    def y_position(self):
        return self.y

class Paddle(games.Sprite):
    """ A paddle that can only partly leave the screen. """
    image = games.load_image("paddle.png")

    def __init__(self, game, x, y):
        """ Initialise paddle sprite."""
        super(Paddle, self).__init__(image = Paddle.image, x = x, y = y)

    def update(self):
        """ Prevent sprite from completely leaving the screen. """
        if self.top < -33:
            self.top = -33

        if self.bottom > games.screen.height + 33:
            self.bottom = games.screen.height + 33

class Human_paddle(Paddle):
    """ A paddle controlled by the player. """

    def update(self):
        """ Move paddle to mouse position. """
        super(Human_paddle, self).update()

        self.y = games.mouse.y

class Computer_paddle(Paddle):
    """ A paddle controlled by the computer. """
    MAX_SPEED = 1

    def update(self):
        """ Move paddle towards ball's position on Y-axis. """
        super(Computer_paddle, self).update()

        ball_y = ball.y_position()

        if ball_y > self.y:
            self.y += MAX_SPEED
        if ball_y < self.y:
            self.y -= MAX_SPEED

3 个回答

2

你需要在任何地方创建一个Ball类的实例,并让这个实例可以被Computer_paddle实例使用。

我建议你可以创建一个管理类,这个类负责组织游戏,并且有一些属性可以让球拍访问。(或者你也可以从games模块的Game类继承一个新类。)

class GameHandle(object):
    def __init__(self):
        self.game = games.Game() # or however to create a game instance
        self.ball = Ball(self.game, 0, 0)
        self.player1 = Human_paddle(self.game, -100, 0, self)
        self.player2 = Computer_paddle(self.game, 100, 0, self)

class Paddle(games.Sprite):
    def __init__(self, game, x, y, handle):
        # ...
        self.handle = handle

class Computer_paddle(Paddle):
    def update(self):
        # ...

        ball_y = self.handle.ball.y_position()

        # ...
3

现在你为“球”这个类定义的所有属性和方法都是针对具体实例的:要访问它们,你需要

  • 创建一个球的实例
  • 然后把这个球的实例传递给需要了解它的球拍实例

所以代码大概是这样的:

在代码的某个地方创建一个球的实例:

ball_1=Ball(game, 0,0)

然后把你的球拍的更新方法改成可以接受一个球的实例作为参数:

def update(self,ball):

当你在任何需要知道球的球拍上调用更新方法时:

my_paddle.update(ball_1)

这样,球拍对象就会知道你想要访问哪个球的y坐标。

当然,你可以用很多不同的方法来做到这一点,只要你能把一个球的实例传递给球拍,这样它就知道哪个球需要查询它的y坐标。

希望这对你有帮助!

3

不可以,不过你需要有一个对象的引用才能访问它的方法。因为你从来没有把 ball 绑定到任何东西上,所以没有对象可以调用这些方法。你是不是想在全局范围内把 ball 创建成 Ball 的一个实例呢?

撰写回答