Access class variable from function in Python
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
.
Related videos on Youtube
maurock
Updated on June 04, 2022Comments
-
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)
aftereat()
is called, it still prints alwaysFalse
class Player(object): eaten = False def move(): print(self.eaten) def eat(Player): Player.eaten = True
Thank you!
-
Arda Arslan almost 6 years
-
MooingRawr almost 6 yearsWhat 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 calleat(Player)
thenprint(Player.eaten)
I seeTrue
... -
maurock almost 6 yearsYes I am sure, because inside an additional method in
Player
, when Iprint(eaten)
it always prints False, even aftereat()
was called
-
-
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 indeeddef eat(Player, Food)
. -
maurock almost 6 yearsIt is already as you suggested. It is a method outside th class, already
Player.eaten = True
-
blue_note almost 6 years@MauroComi: how do you call that function??
-
maurock almost 6 yearsin the main
eat(player1)
, beingplayer1 = Player()
-
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 about 4 years@maurock It may be useful for you to look into Composition