iswg
iswg

Reputation: 195

How to change a class attribute inside __init__?

class Ant:
    count = 0

    def __init__(self):
        if count == 0:
            self.real = True
        else:
            self.real = False
        count += 1

So basically what I want to achieve is I want only the first instance of this class to have the "real" attribute to be True, and the subsequent attributes to be False. I know right now this is going to give me unboundlocal error for count. How do I make this work?

Upvotes: 7

Views: 9301

Answers (2)

jsbueno
jsbueno

Reputation: 110696

Prefer using self.__class__.variable - unless you want the same variable to be shared by all subclasses.

In code like this:

class Ant:
    count = 0

the "count" value is stored in the class' __dict__ attribute. If you do something like:

class Ant:
    count = 0
    def __init__(self):
         print(self.count)

The attrobute access mechanism defined in Python's Data Model will see there is no instance of count in the instance "self", and retrieve the value from its class. So, if you are reading a value from a class variable, you can use it jus tlike a normal instance.

However, if your code goes like:

def __init__(self):
    self.count += 1

What happens ins an entire different things: Python Reads the attribute from the class as above, adds 1 to it, and stores the new result in the instance.

So, whenever you want to access the class value, you can either hard-code the class name - (since when the method code is run, the class is already created and is "known"):

class Ant:
    count = 0
    def __init__(self):
         Ant.count += 1

Or, better yet, use the instance's __class__ attribute - that way you will always get the variable value for the proper subclass

class Ant:
     count = 0
     def __init__(self):
         self.__class__.count += 1

class FireAnt(Ant):
     count = 0

(Note that, like in the second example above, if the subclass contains no own count variable, the value from the superclass' count will be read, a new one will be created on the subclass the first time this code is run)

Upvotes: 3

omri_saadon
omri_saadon

Reputation: 10669

Change count ToAnt.count

As count is a class member (shared between all instances of Ant class) and does not belong to a specific instance you should use it with the prefix of the class name.

class Ant:
    count = 0

    def __init__(self):
        if Ant.count == 0:
            self.real = True
        else:
            self.real = False
        Ant.count += 1

Upvotes: 11

Related Questions