Access class variable from function in Python

13,558

Solution 1

eaten should be a instance variable, not a class variable - you can have some players eaten and others not, and having it as a class variable means it would affect all players, which is probably not what you want.

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

Solution 2

When you create a class, you want to create instance variables for stuff like this. Instance variables are variables that can be different for each instance of the Class you are creating. You do this by defining it as a variable "self.var" in the init method, like so

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

This sets the default value of eaten for every new instance of Player to be False. Whenever we do something like foo = Player(), there is an instance variable like foo.eaten which defaults to being False. Now if we want to update that with a method, we need to reference the instance of Player whose instance variable we are updating, usually with the parameter called self

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

    def eat(self):
        self.eaten = True

Now when we do foo.eat(), Python passes in foo as the first parameter to the function eat, meaning self.eaten is really looking at foo.eaten. Therefore when we say self.eaten = True we are setting the instance variable of foo.eaten to True.

Share:
13,558

Related videos on Youtube

maurock
Author by

maurock

Updated on June 04, 2022

Comments

  • maurock
    maurock almost 2 years

    I'm coding my first python game using OOP and I have some problems with the access to class variables. Specifically, I want to have access to a class variable from a method. For some variables it works, but for a specific boolean variable it does not work:

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

    The problem is that, when the function is called, eaten does not override the variable in the class. For other variables it does correctly what I want though.

    EDIT: If, inside a method in the Class player, I add print(self.eaten) after eat() is called, it still prints always False

     class Player(object):
        eaten = False
    
        def move():
            print(self.eaten)
    
    def eat(Player):
        Player.eaten = True
    

    Thank you!

    • Arda Arslan
      Arda Arslan almost 6 years
    • MooingRawr
      MooingRawr almost 6 years
      What do you mean by for other variables it does correctly? Also are you sure? If I copy and paste your code (giving __init__ a pass) and call eat(Player) then print(Player.eaten) I see True...
    • maurock
      maurock almost 6 years
      Yes I am sure, because inside an additional method in Player, when I print(eaten) it always prints False, even after eat() was called
  • maurock
    maurock almost 6 years
    def eat() needs to be outside the class, since I pass actually two classes in it, so I cannot do it inside an other class. It is indeed def eat(Player, Food).
  • maurock
    maurock almost 6 years
    It is already as you suggested. It is a method outside th class, already Player.eaten = True
  • blue_note
    blue_note almost 6 years
    @MauroComi: how do you call that function??
  • maurock
    maurock almost 6 years
    in the main eat(player1), being player1 = Player()
  • nosklo
    nosklo almost 6 years
    @MauroComi ok, I edited my answer, but this is confusing! You should pass instances around, not classes, and you should use lower case variable names for instances. See my answer.
  • pfabri
    pfabri about 4 years
    @maurock It may be useful for you to look into Composition