Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Changing class attribute not working as expected

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading