Multiple instances of the same class being rewritable at the same time? (Python)

Here is a very simple code that I made to demonstrate the problem I am facing. What happens here is that I create two different instances of the same class, but changing the attribute of one will change the corresponding attribute of the other instance. I do not know why this is so. Is this a common occurrence in Python, or am I encountering something that is completely confused?

class exampleClass(object): attribute1=0 attribute2="string" x=exampleClass x.attribute1=20 x.attribute2="Foo" y=exampleClass y.attribute1=60 y.attribute2="Bar" print("X attributes: \n") print(x.attribute1) print(x.attribute2) print("Y attributes: \n") print(y.attribute1) print(y.attribute2) 

Here's what the program coming out of my console looks like:

 >>> X attributes: 60 Bar Y attributes: 60 Bar >>> 

I think he should say:

 X attributes: 20 Foo Y attributes: 60 Bar 

What am I doing wrong?

+6
source share
4 answers

You create class attributes if you want instance attributes. Use this:

 class exampleClass(object): def __init__(self): self.attribute1 = 0 self.attribute2 = "string" 

Also, you are not instantiating exampleClass, you need the following:

 x = exampleClass() y = exampleClass() 

Your code simply uses the new names for the class and changes its attributes.

+8
source

You have assigned attributes to the attribute class. This means that they are attached to the class itself, and not to class objects.

If you want to view objects, you can do something like:

 class exampleClass(object): def __init__(self): self.attribute1=0 self.attribute2="string" x = exampleClass() y = exampleClass() 

Then, when you change the value of an attribute of an object, it affects only the concrete, and not ALL objects of this class.

+4
source

Modifications are made so that they are more understandable.

With the code that you have, your problem is that you make the x and y variables refer to the class definition and not to the creation of objects, which, in my opinion, have now appeared as a problem in all discussions and posts.

 x = exampleClass 

Now means that x now points to a class definition. This is interesting because since you have attribute1 as an exampleClass variable, you can do this:

 x.attribute1 = 3 

Now, if you have done the following:

 exampleClass.attribute1 

Instead of seeing 0 as you originally installed it, you will see 3!

To create class objects, you need to do the following:

 x = exampleClass() y = exampleClass() 

Now both variables refer to new objects, each of which has its own attributes, so if you did this:

 x.attribute1 = 219 

Then you will find that y.attribute1 is not changed :) Using the class name and function is common in python as a reference to the definition. Therefore, be careful if you want to instantiate an object, do not forget to use parentheses, if you want to call a function, make sure you do it too, otherwise the use of this name is a reference to the definition.

I suggest you read the answer of Ned Batchelder, though (and others now), since you have to make instance variables this way with the init function, since it is much cleaner and more in line with the design standards that most follow.

But in general, since it inherits from the Object class, you can assume that executing it this way will create instances (with parentheses), etc., and therefore you can change the values ​​of the object, since I believe that they should be variables instance, even without "self" ".

+3
source

Classes are also objects in Python. Therefore, they can be assigned to variables and have their own attributes, the same as any other object.

All the names that you associate in the class block become attributes of the class being created. They are not attributes of future instances of this class. But when you try to read an attribute from an instance, and the instance does not have this attribute, Python by default considers the class attributes of the instance and returns this if it finds it. In fact, how methods work in Python; they are just attributes in the class, and when you try to extract them from the instance (where they do not exist), you can find them by looking at the class.

With this in mind, your program does not do what you think.

 class exampleClass(object): attribute1=0 attribute2="string" 

Here you created a class called exampleClass with two attributes attribute1 and attribute2 . They are not instance attributes; this is really a common mistake made by people learning Python. You need to educate yourself on this, because for simple examples it will often work β€œas if” they were instance attributes. The binding names in the class block create attributes of the class object. The only way to create attributes of an instance is to get a link to the instance after its existence and assign attributes to it; Python provides you with the __init__ method (which will be called when the instance is created) as a place to do this.

So, the basic rule of thumb: the names defined in the class block are attributes of the class object, the names assigned as self attributes in __init__ are attributes in all instances of this class.

Your confusion is further compounded by another problem:

 x=exampleClass x.attribute1=20 x.attribute2="Foo" 

Since classes are objects like everything else in Python, this is perfectly reasonable Python code, but it does not do what you think. You have not actually instantiated your class; for this you need to call the class, as in exampleClass() . The gothic name exampleClass simply refers to the object of the class itself, so you just bind this name x to this object and then assigned some of its attributes. Naturally, when you then bind y to an object of the class and assign attributes to this object through y , the object referenced by x is affected (this is the same object).

+1
source

Source: https://habr.com/ru/post/919081/


All Articles