Coder Perfect

In Python, the proper approach to define class variables [duplicate]

Problem

In Python, I’ve discovered that class attributes are initialized in two different ways.

The first method is as follows:

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

  def __init__(self):
    #pass or something else

The other design is as follows:

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

Which method is the best for initializing class attributes?

Asked by jeanc

Solution #1

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

With some code, you’ll be able to see it more clearly:

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, the class element changed for both objects when we updated it. The other object, however, stayed untouched when the object element was modified.

Answered by juliomalegria

Solution #2

This example, I believe, demonstrates the differences between the styles:

james@bodacious-wired:~$cat test.py 
#!/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
james@bodacious-wired:~$./test.py 
['__doc__', '__init__', '__module__', 'element1']
--
['__doc__', '__init__', '__module__', 'element1', 'element2']
--
Hello World
Hello
Traceback (most recent call last):
  File "./test.py", line 17, in <module>
    print MyClass.element2
AttributeError: class MyClass has no attribute 'element2'

element1 is associated with the class, while element2 is associated with a specific instance of the class.

Answered by James Polley

Post is based on https://stackoverflow.com/questions/9056957/correct-way-to-define-class-variables-in-python