Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compound assignment to Python class and instance variables

Tags:

python

class

I've been trying to understand Python's handling of class and instance variables. In particular, I found this answer quite helpful. Basically it says that if you declare a class variable, and then you do an assignment to [instance].property, you will be assigning to a different variable altogether -- one in a different namespace from the class variable.

So then I considered -- if I want every instance of my class to have a member with some default value (say zero), should I do it like this:

class Foo:
    num = 0

or like this?

class Foo:
    def __init__(self):
        self.num = 0

Based on what I'd read earlier, I'd think that the second example would be initializing the 'right' variable (the instance instead of the class variable). However, I find that the first method works perfectly well too:

class Foo:
    num = 0

bar = Foo()
bar.num += 1 # good, no error here, meaning that bar has an attribute 'num'
bar.num
>>> 1
Foo.num
>>> 0 # yet the class variable is not modified! so what 'num' did I add to just now?

So.. why does this work? What am I not getting? FWIW, my prior understanding of OOP has come from C++, so explanation by analogy (or pointing where it breaks down) might be useful.

like image 441
int3 Avatar asked Mar 11 '10 11:03

int3


People also ask

What is the difference between class variable and instance variable in Python?

Class variables are shared across all objects while instance variables are for data unique to each instance. Instance variable overrides the Class variables having same name which can accidentally introduce bugs or surprising behaviour in our code.

Can a class method access instance variables Python?

There are two ways to access the instance variable of class: Within the class in instance method by using the object reference ( self ) Using getattr() method.

How do you assign a class to a variable in Python?

Use dot notation or setattr() function to set the value of class attribute. Python is a dynamic language. Therefore, you can assign a class variable to a class at runtime. Python stores class variables in the __dict__ attribute.

What is difference between instance variable and class variable?

Class variables also known as static variables are declared with the static keyword in a class, but outside a method, constructor or a block. Instance variables are created when an object is created with the use of the keyword 'new' and destroyed when the object is destroyed.


2 Answers

Personally, I've found these documents by Shalabh Chaturvedi extremely useful and informative regarding this subject matter.

bar.num += 1 is a shorthand for bar.num = bar.num + 1. This is picking up the class variable Foo.num on the righthand side and assigning it to an instance variable bar.num.

like image 195
MattH Avatar answered Oct 22 '22 10:10

MattH


In the following code, num is a class member.

class Foo:
    num = 0

A C++ equivalent would be something like

struct Foo {
  static int num;
};

int Foo::num = 1;

class Foo:
    def __init__(self):
        self.num = 0

self.num is an instance member (self being an instance of Foo).

In C++, it would be something like

struct Foo {
  int num;
};

I believe that Python allows you to have a class member and an instance member sharing the same name (C++ doesn't). So when you do bar = Foo(), bar is an instance of Foo, so with bar.num += 1, you increment the instance member.

like image 37
Bertrand Marron Avatar answered Oct 22 '22 09:10

Bertrand Marron