correct way to define class variables in Python


Possible Duplicate:
Variables inside and outside of a class __init__() function

I noticed that in Python, people initialize their class attributes in two different ways.

The first way is like this:

class MyClass:
  __element1 = 123
  __element2 = "this is Africa"

  def __init__(self):
    #pass or something else

The other style looks like:

class MyClass:
  def __init__(self):
    self.__element1 = 123
    self.__element2 = "this is Africa"

Which is the correct way to initialize class attributes?

5/23/2017 11:55:07 AM

Accepted Answer

Neither way is necessarily correct or incorrect, they are just two different kinds of class elements:

  • Elements outside the __init__ method are static elements; they belong to the class.
  • Elements inside the __init__ method are elements of the object (self); they don't belong to the class.

You'll see it more clearly with some code:

class MyClass:
    static_elem = 123

    def __init__(self):
        self.object_elem = 456

c1 = MyClass()
c2 = MyClass()

# Initial values of both elements
>>> print c1.static_elem, c1.object_elem 
123 456
>>> print c2.static_elem, c2.object_elem
123 456

# Nothing new so far ...

# Let's try changing the static element
MyClass.static_elem = 999

>>> print c1.static_elem, c1.object_elem
999 456
>>> print c2.static_elem, c2.object_elem
999 456

# Now, let's try changing the object element
c1.object_elem = 888

>>> print c1.static_elem, c1.object_elem
999 888
>>> print c2.static_elem, c2.object_elem
999 456

As you can see, when we changed the class element, it changed for both objects. But, when we changed the object element, the other object remained unchanged.

1/3/2019 7:12:37 PM

I think this sample explains the difference between the styles:

#!/usr/bin/env python

class MyClass:
    element1 = "Hello"

    def __init__(self):
        self.element2 = "World"

obj = MyClass()

print dir(MyClass)
print "--"
print dir(obj)
print "--"
print obj.element1 
print obj.element2
print MyClass.element1 + " " + MyClass.element2
['__doc__', '__init__', '__module__', 'element1']
['__doc__', '__init__', '__module__', 'element1', 'element2']
Hello World
Traceback (most recent call last):
  File "./", line 17, in <module>
    print MyClass.element2
AttributeError: class MyClass has no attribute 'element2'

element1 is bound to the class, element2 is bound to an instance of the class.

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow