Summary of the use of class variables and member variables in python

  • 2020-05-30 20:31:33
  • OfStack

preface

Recently, I was writing a project with python, and found that a disgusting bug would interact with the data between two instances generated by a class, which made me very confused. Later, I was reminded that java has class variables and instance variables, so I consulted relevant materials and found that python also has similar class variables and instance variables. Let's take a look at the detailed introduction below.

Take a look at the sample code below:


class A:
 x = 0
 def __init__(self):
 self.y = 0

x is the class variable, y is the instance variable.

It is not wrong in principle, but I found some disgusting problems when I actually used it (that is, I have been looking for bug for 3 days)... For example, the following code:


class A:
 x = []
 y = 0
 def __init__(self):
 pass
 def add(self):
 self.x.append('1')
 self.y+=1
a=A() 
print a.x,a.y
print A.x,A.y
a.add()
print a.x,a.y
print A.x,A.y
b=A() 
print b.x,b.y
print A.x,A.y

It is obvious that x and y are class variables, while add is used to modify x and y, respectively. Then construct an instance a, modify the value of the instance a, and finally construct the instance b.

He thought the result was obvious, but the result was:


[] 0
[] 0
['1'] 1
['1'] 0
['1'] 0
['1'] 0

What's the problem? When x and y are class variables, why are a.x and b.x1 in group 2 of print different from a.y and b.y?

Thought for a long time to realize a truth... That is, for python, class variables are really something that all classes have in common. But that's if we use the same reference, for example, the append method for the [] object is a common class variable; However, for assignment statements, if an assignment statement is used on a class variable in a class, python will generate a copy of the object based on which future operations will be performed without affecting the original class object. This explains the above phenomenon.

So in order to prevent yourself from forgetting the difference between class variables and instance variables and thus making them public when you don't want to make them public, the best way is to reinitialize 1 when you use a variable in each class, so that it doesn't cause surprises.

conclusion


Related articles: