从Python函数中访问类变量

3

我正在使用面向对象编程编写我的第一个Python游戏,但是我在访问类变量时遇到了一些问题。具体来说,我想从一个方法中访问一个类变量。对于某些变量,它可以正常工作,但对于一个特定的布尔变量,它无法正常工作:

class Player(object):
    eaten = False

    def __init__(self):
          .....

def eat(Player):
    Player.eaten = True

问题在于,当调用函数时,eaten没有覆盖类中的变量。但对于其他变量,它确实按照我的意愿执行正确的操作。
编辑: 如果在类player的方法中,在调用eat()后添加print(self.eaten),它仍然始终打印False
 class Player(object):
    eaten = False

    def move():
        print(self.eaten)

def eat(Player):
    Player.eaten = True

谢谢!


“在类定义内部声明的变量,但不在方法内部声明的变量是类或静态变量。”(来源:https://dev59.com/3nVD5IYBdhLWcg3wKYL-) - Arda Arslan
1
“对于其他变量,它的行为是正确的” 是什么意思?而且你确定吗?如果我复制并粘贴您的代码(给__init__传递一个 pass),然后调用eat(Player),然后print(Player.eaten),我会看到 True ... - MooingRawr
是的,我确定,因为在Player类的另一个方法中,当我打印 eaten 时,它总是打印False,即使已经调用了eat()方法。 - maurock
3个回答

6

eaten 应该是一个实例变量,而不是一个类变量 - 你可以有一些玩家被吃掉而另一些没有被吃掉,将其作为类变量意味着它会影响所有玩家,这可能不是你想要的。

class Player(object):
    def __init__(self):
        self.eaten = False

    def move(self):
        if self.eaten:
            print("I have eaten so I can move")
        else:
            print("I can't move! I'm hungry!")

def eat(player, food):
    player.eaten = True # change `eaten` for the player
                        # passed as parameter!

 >>> p = Player() # creates a instance of the Player class
 >>> q = Player() # creates another instance of the Player class
 >>> eat(p, 'apple') # player `p` eates apple
 >>> p.move()
 I have eaten so I can move
 >>> q.move()
 I can't move! I'm hungry!

 print(p.eaten) # will print True
 print(q.eaten) # will print False

“def eat()”需要放在类外面,因为我实际上在其中传递了两个类,所以我不能将其放在另一个类内部。它确实是“def eat(Player, Food)”。 - maurock
@MauroComi 好的,我编辑了我的回答,但这很令人困惑!你应该传递实例而不是类,并且你应该使用小写变量名称来表示实例。请查看我的回答。 - nosklo
@maurock,你可能会对组合感兴趣。 - pfabri

1
当您创建一个类时,您希望为此类创建实例变量,以存储诸如此类的内容。实例变量是指每个创建的类实例都可以具有不同值的变量。您可以通过在init方法中将其定义为变量"self.var"来实现这一点。
class Player(object):
    def __init__(self):
        self.eaten = False

这将为每个新的Player实例设置eaten的默认值为False。每当我们执行类似于foo = Player()的操作时,都会有一个实例变量foo.eaten,其默认值为False。现在,如果我们想使用方法更新它,我们需要引用正在更新实例变量的Player实例,通常使用名为self的参数进行引用。
class Player(object):
    def __init__(self):
        self.eaten = False

    def eat(self):
        self.eaten = True

现在当我们执行foo.eat()时,Python将foo作为第一个参数传递给函数eat,这意味着self.eaten实际上是查看foo.eaten。因此,当我们说self.eaten = True时,我们正在将foo.eaten的实例变量设置为True

0
当你调用函数时,你传递的是一个对象,而不是类。所以,你在实例上分配了变量。将你的函数改为:
def eat(player): type(player).eaten = True 其中type(player)返回实际的Player类。

已经按照您的建议完成了。这是一个在类之外的方法,Player.eaten = True 已经实现。 - maurock
@MauroComi:你怎么称呼那个函数?? - blue_note
在主函数中,执行 eat(player1),其中 player1 = Player() - maurock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接