References and class attributes in Python have recently studied object reference mechanism in Python, leaving notes for reference.
The first thing is clear: "Everything in Python is an object 」.
So what exactly does this mean?
The following code:
#! /Usr/bin/env pythona = [0, 1, 2] # Here is a simple list # initially, the list and the IDs of each element are like this. Print 'origin' print id (a), afor x in a: print id (x ), xprint '--------------------' # change the first element to print 'after change a [0] 'A [0] = 4 print id (a), afor x in: print id (x), xprint '--------------------' # change the second element to print 'after changing a [1] 'A [1] = 5 print id (), afor x in a: print id (x), xprint '--------------------' # Let's look back and write 0 directly. how much print 'How about const 0 is the id? 'Print id (0), 0
The running result is as follows:
PastgiftMacbookPro:python pastgift$ ./refTest.py Origin4299760200 [0, 1, 2]4298181328 04298181304 14298181280 2----------------------after change a[0]4299760200 [4, 1, 2]4298181232 44298181304 14298181280 2----------------------after change a[1]4299760200 [4, 5, 2]4298181232 44298181208 54298181280 2----------------------how about const 0?4298181328 0
From the "Origin" section, the addresses of each element in the list are exactly 24 different, pointing to their own data in turn-this reminds me of arrays.
When the value of a [0] is modified, the address of a [0] is changed. That is to say, the value assignment statement only allows a [0] to point to another object again. In addition, it is noted that the address of a [0] differs from the address of a [2] by 48 (2 24 ).
After a [1] is modified again, the address of a [1] also changes. Interestingly, the address of a [1] is 24 different from that of a [0], and 72 (3 24) different from that of a [2 ).
Finally, when the address 0 is printed directly, it is found that its address is exactly the same as the address of the first a [0.
At this point, we can basically explain that even the elements in the list are actually references. Modifying the element in the list is actually modifying the reference.
For class attributes in Python, it is mentioned that "class attributes are shared between the same class and its subclass. modifying class attributes affects all objects of the same class and its subclass 」.
It sounds scary, but after careful research, it is not a big deal.
The following code:
#! /Usr/bin/env pythonclass Bird (object): name = 'bird' talent = ['fly '] class Chicken (bird): passbird = Bird (); bird2 = Bird (); # chicken = Chicken (); # Subclass instance # print 'original' print id (bird. name), bird. nameprint id (bird. talent), bird. talentprint id (bird2.name), bird2.nameprint id (bird2.talent), bird2.talentprint id (chicken. name), chicken. nameprint id (chicken. talent), chicken. talentprint '----------------------------' # Change the name to see if bird. name = 'bird name changed! 'Print 'after changing name' print id (bird. name), bird. nameprint id (bird. talent), bird. talentprint id (bird2.name), bird2.nameprint id (bird2.talent), bird2.talentprint id (chicken. name), chicken. nameprint id (chicken. talent), chicken. talentprint '----------------------------' # try a gift (modify the elements in the class attributes) bird. talent [0] = 'walk 'Print' after changing talent (a list) 'Print id (bird. name), bird. nameprint id (bird. talent), bird. talentprint id (bird2.name), bird2.nameprint id (bird2.talent), bird2.talentprint id (chicken. name), chicken. nameprint id (chicken. talent), chicken. talentprint '----------------------------' # Change to a new talent tree (change all class attributes) bird. talent = ['swim '] print 'after reassign talent' print id (bird. name), bird. nameprint id (bird. talent), bird. talentprint id (bird2.name), bird2.nameprint id (bird2.talent), bird2.talentprint id (chicken. name), chicken. nameprint id (chicken. talent), chicken. talentprint '----------------------------' # Remove the New Talent Tree (modify the elements in the new class attributes) bird. talent [0] = 'Dance 'print 'changing element after reassigning talent' print id (bird. name), bird. nameprint id (bird. talent), bird. talentprint id (bird2.name), bird2.nameprint id (bird2.talent), bird2.talentprint id (chicken. name), chicken. nameprint id (chicken. talent), chicken. talentprint '----------------------------'
Running result:
PastgiftMacbookPro:python pastgift$ ./changeAttributeTest.py Original attr4301998000 bird4301857352 ['fly']4301998000 bird4301857352 ['fly']4301998000 bird4301857352 ['fly']----------------------------after changing name4301986984 bird name changed!4301857352 ['fly']4301998000 bird4301857352 ['fly']4301998000 bird4301857352 ['fly']----------------------------after changing talent(a list)4301986984 bird name changed!4301857352 ['walk']4301998000 bird4301857352 ['walk']4301998000 bird4301857352 ['walk']----------------------------after reassign talent4301986984 bird name changed!4301859512 ['swim']4301998000 bird4301857352 ['walk']4301998000 bird4301857352 ['walk']----------------------------changing element after reassigning talent4301986984 bird name changed!4301859512 ['dance']4301998000 bird4301857352 ['walk']4301998000 bird4301857352 ['walk']----------------------------
When "Origin" is used, the addresses of the same class attributes of similar objects and subclass objects are the same-this is the so-called "sharing 」.
After the name is modified, only the name attribute of the modified object changes. This is because the value assignment operation for name is actually replacing a string and referencing it again. The string itself has not changed. So there is no mutual influence between the same type and the subclass.
Next, modify the elements in the talent. At this time, the situation has changed: the talent attributes of the same type and its sub-classes have all changed. this is easy to understand because they all reference the same memory address and reference the same object.
Next, assign a value to the talent, that is, change it to reference another object. The result is that only the talent attribute of this instance has changed. From the memory address, we can see that the talent attribute of this instance and other instances no longer point to the same object. That is to say, "This instance is already an outsider 」.
After the elements in the talent are modified again, the results that have no impact on other instances are also well understood. Because it is already a "out-of-the-box person", it is my own business to make any effort.
Therefore, "mutual influence of class attributes on the same type and its sub-classes" must have one precondition: After an instance is created, its class attributes have never been assigned a new value, that is, the class property still points to the memory address initially pointed.
Finally, we will mention the object attributes.
The following code:
#! /Usr/bin/env pythonclass Bird (object): def _ init _ (self): self. talent = ['fly '] bird = Bird () bird2 = Bird () # print 'origin' print id (bird. talent), bird. talentprint id (bird2.talent), bird2.talentprint '------------------' # Modify the attribute bird of an object. talent [0] = 'walk 'print 'after changing attribute 'print id (bird. talent), bird. talentprint id (bird2.talent), bird2.talentprint '------------------' # dead: the attributes of the two objects point to the same memory address, and then modify bird. talent = bird2.talentbird. talent [0] = 'swim 'print' assign to another attribute and change it 'print id (bird. talent), bird. talentprint id (bird2.talent), bird2.talentprint '------------------' running result: PastgiftMacbookPro: python pastgift $. /changeAttributeTest2.py pipeline ['fly '] 4299760200 ['fly'] ------------------ after changing pipeline ['walk '] 4299760200 ['fly'] ------------------ assign to another attribute and change it4299760200 ['swim '] 4299760200 ['swim'] --------------------
Even if the object attributes have the same content (the attributes after initialization are generally the same), they are allocated to completely different memory addresses. Therefore, there is no "impact between similar objects.
However, if the attribute of one object and the attribute of another object point to the same address, the two (but only between the two) will be associated with each other.