Here is a simplified running code to show my problem:
class c_event():
cl_attr = None
def __init__(self, mystring):
print(self.cl_attr)
if self.cl_attr is None:
self.cl_attr = mystring
print(self.cl_attr)
var1 = c_event('123')
var2 = c_event('456')
print(var1.cl_attr)
print(var2.cl_attr)
print(c_event.cl_attr)
I am under the assumption that a class attribute defined like I did is common, read- and writeable by all instances of that class. So I expected to get an output of:
None
123
123
123
123
123
123
Instead I get:
None
123
None
456
123
456
None
What is the (thinking) mistake I made?
***Edit: Chepners answer helped understanding. Here is the code that does what I want:
class c_event():
cl_attr = None
def __init__(self, mystring):
print(c_event.cl_attr)
if c_event.cl_attr is None:
c_event.cl_attr = mystring
print(c_event.cl_attr)
var1 = c_event('123')
var2 = c_event('456')
print(var1.cl_attr)
print(var2.cl_attr)
print(c_event.cl_attr)
>Solution :
You can only change a class attribute by assigning to the attribute via the class itself, not an instance. __init__ is creating a new instance attribute that subsequently shadows the class attribute.
class c_event():
cl_attr = None
def __init__(self, mystring):
print(self.cl_attr)
if self.cl_attr is None:
type(self).cl_attr = mystring
print(self.cl_attr)
It’s not clear that you should be modifying a class attribute like this in the first place. Basically, cl_attr is remembering the value used to create the first instance of c_event.
If you really just want to set the instance attribute, the class attribute isn’t necessary at all:
class c_event:
def __init__(self, mystring):
self.attr = mystring