-1

I have a problem about Classes and I can explain it with Python codes. Code:

class Game:
    variable = 0
    def function(self):
        print("This is a message inside the class.")

a = Game()
a.variable += 1

a = Game()
a.variable += 1
print(a.variable)

I want to get result 2 when I am using it with classes. Let me explain why I want it. Because I am using socket and for every user in "Game" class online variable's value increasing 1. For every user It's creating new instance for Game class (in function connection_made). Because of creation of instance value is 1.

Skandix
  • 1,916
  • 6
  • 27
  • 36
  • 1
    Possible duplicate of [Python: Difference between class and instance attributes](https://stackoverflow.com/questions/207000/python-difference-between-class-and-instance-attributes) – Skandix Feb 14 '18 at 15:08
  • The `a` is being overwriten when you call `a = Game()` the second time. – Sqoshu Feb 14 '18 at 15:08
  • either instantiate `a` once, or make `variable` static – Omar Einea Feb 14 '18 at 15:08
  • You are loading the class into `a` when you have the second line of `a = Game()` thus erasing the first call to set variable to +=1. – Zack Tarr Feb 14 '18 at 15:08
  • @OmarEinea My first instinct was to say `variable` *is* ”static”, but of course only `Game.variable` not the `variable` attribute on the instances that gets created by `+=`. :-) – BlackJack Feb 14 '18 at 15:11
  • I also recommend reading this: [blog.lerner.co.il/python-attributes](http://blog.lerner.co.il/python-attributes/) – Skandix Feb 14 '18 at 15:12
  • You may want to use `Game.variable` instead of `a.variable` ? – Laurent H. Feb 14 '18 at 15:12

3 Answers3

1

If I understund it correctly, you want to count the instances of the class Game. Something like this will do the job:

class Game:
    _count = 0  # class attribute

    def __init__(self):
        Game._count += 1
        self.variable = Game._count  # instance attribute

    # rest of the code...

a = Game()
b = Game()
print(a.variable)  # 1
print(b.variable)  # 2
Andreas K.
  • 9,282
  • 3
  • 40
  • 45
0

First of all, to explain it easier, you have to know that doing a.variable += 1 is the same that doing a.variable = a.variable + 1.

Now, that being said, here is "the problem". The thing here, is that when you access a.variable, the interpreter doesn't find the attribute in the instance, so it look that attribute on the class. When it find it, it will return that value. So, a.variable = a.variable + 1 becomes a.variable = 0 + 1. Now, the interpreter will go to the instance, and look for the attribute variable. It doesn't find it, so it create it and set it as one. But what? Then you never changed the attribute variable from the class Game? The answer is no. To check this, try this code.

class Game:
    variable = 0
    def function(self):
        print("This is a message inside the class.")

a = Game()
print('Instance attributes before set:', a.__dict__)
print('Class attributes before set', Game.__dict__)
a.variable += 1
print('Instance attributes before set:', a.__dict__)
print('Class attributes after set:', Game.__dict__)

As you can see, you never changed the class atribute. If you want to change the class attribute, you have to do

Game.variable += 1

Hope it helps

jtagle
  • 302
  • 1
  • 8
0

a.variable += 1 is short for a.variable = a.variable + 1. What happens here is that a.variable on the right hand side of the assignment refers to Game.variable and has the value 0 and then a new instance attribute variable is created on a with the value 0+1=1. Game.variable is never changed, i.e. assigned a new value.

If you want to increase Game.variable you actually have to assign the incremented value to the class Game, not instances.

Having said that: You don't really want to have global counters of things on classes. This is not flexible and it is error prone. Have a container with user objects somewhere to keep track of the users and query that container for its length if you need to know the number of users.

BlackJack
  • 4,476
  • 1
  • 20
  • 25