We have a class with static members. Some members are immutable objects and some are not:
class Test:
x = 0
y = 'ok'
z = [1, 2, 3]
t1 = Test()
t2 = Test()
When printing the variables you get what you would expect:
print(t1.x, t2.x)
print(t1.y, t2.y)
print(t1.z, t2.z)
0 0
ok ok
[1, 2, 3] [1, 2, 3]
And I can modify the value of the immutable static members:
Test.x = 1
print(t1.x, t2.x)
1 1
But I can also modify these values separately for each instance:
t1.x = 5
t2.x = 7
print(t1.x, t2.x)
5 7
Same happens to strings:
Test.y = 'okk'
print(t1.y, t2.y)
t1.y = 'foo'
t2.y = 'bar'
print(t1.y, t2.y)
okk okk
foo bar
But with the immutable members things are different:
Test.z += [4]
print(t1.z, t2.z)
t1.z += [5]
t2.z += [6]
print(t1.z, t2.z)
[1, 2, 3, 4] [1, 2, 3, 4]
[1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
The instance-based member access also affects the other instances of the class.
I would like to know more about how these "static" members behave in the background. Using my own knowledge I was able to think of the following:
I know ints are immutable, so while both
t1
andt2
may point to the same0
or1
instance, I guess when we assign them different values, they start pointing to different memory locations.I guess Point 1. is possible because Python lacks a proper implementation for a lot of features, classes and namespaces are basically the same thing, we do not have a completely implicit
self
/this
and we still have to specify it, no properprivate
/protected
access, no properconst
-ness. So it is not hard for me to believe (but I would like confirmation or more info on this) that Python also does not have a proper implementation of the concept of "static" class members. One possibility I can think of is that all "static" member are actually instance members andTest.x
is just a syntactic sugar for iterating and reassigning ALL instances ofTest.x
.Point 2. would explain this behaviour, and why the immutable object access, even through instances, affects all instances, because
Test.z
is not being reassigned, only accessed, and then methods of that object are called (such as__iadd__
).
Is this correct? Or what exactly is the mechanism for the "static but not really" class members?