How should I choose between using instance vs. class attributes?

Question:

I tried this example code:

class testclass:
    classvar = 'its classvariable LITERAL'
    def __init__(self,x,y):
        self.z = x
        self.classvar = 'its initvariable LITERAL'
        
        self.test()
    
    def test(self):
        print('class var',testclass.classvar)
        print('instance var',self.classvar)
        
if __name__ == '__main__':
    x = testclass(2,3)

I need some clarification. In both cases, I’m able to access the class attribute and instance in the test method.

So, suppose if I have to define a literal that needs to be used across all function, which would be the better way to define it: an instance attribute or a class attribute?

Asked By: user1050619

||

Answers:

You should define it as a class attribute if you want it to be shared among all instances. You should define it as an instance variable if you want a separate one for each instance (e.g., if different instances might have different values for the variable).

Answered By: BrenBarn

Class variables are quite good for “constants” used by all the instances (that’s all methods are technically). You could use module globals, but using a class variable makes it more clearly associated with the class.

There are often uses for class variables that you actually change, too, but it’s usually best to stay away from them for the same reason you stay away from having different parts of your program communicate by altering global variables.

Instance variables are for data that is actually part of the instance. They could be different for each particular instance, and they often change over the lifetime of a single particular instance. It’s best to use instance variables for data that is conceptually part of an instance, even if in your program you happen to only have one instance, or you have a few instances that in practice always have the same value.

Answered By: Ben

It’s good practice to only use class attributes if they are going to remain fixed, and one great thing about them is that they can be accessed outside of an instance:

class MyClass():
    var1 = 1
    def __init__(self):
        self.var2 = 2

MyClass.var1 # 1 (you can reference var1 without instantiating)
MyClass.var2 # AttributeError: class MyClass has no attribute 'var2'

If MyClass.var is defined, it should be the same in every instance of MyClass, otherwise you get the following behaviour which is considered confusing.

a = MyClass()
b = MyClass()

a.var1, a.var2 # (1,2)
a.var1, a.var2 = (3,4) # you can change these variables
a.var1, a.var2 # (3,4)
b.var1, b.var2 # (1,2) # but they don't change in b
MyClass.var1 # 1         nor in MyClass
Answered By: Andy Hayden

I found this in an old presentation made by Guido van Rossum in 1999 ( http://legacy.python.org/doc/essays/ppt/acm-ws/sld001.htm ) and I think it explains the topic beautifully:

Instance variable rules

On use via instance (self.x), search order:

  • (1) instance, (2) class, (3) base classes
  • this also works for method lookup

On assigment via instance (self.x = …):

  • always makes an instance variable
  • Class variables "default" for instance variables

But…!

  • mutable class variable: one copy shared by all
  • mutable instance variable: each instance its own
Answered By: Juan Fco. Roco
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.