Правильный способ определения переменных класса в Python

Возможный дубликат:
Переменные внутри и снаружи функции __init __()

Я заметил, что в Python люди инициализируют свои атрибуты класса двумя разными способами.

Первый способ:

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

  def __init__(self):
    #pass or something else

Другой стиль выглядит следующим образом:

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

Каков правильный способ инициализации атрибутов класса?

Ответ 1

Оба способа неправильны или неверны, это всего лишь два разных типа элементов класса:

  • Элементы вне метода __init__ являются статическими элементами, это значит, что они принадлежат классу.
  • Элементы внутри метода __init__ являются элементами объекта (self), они не принадлежат классу.

Вы увидите это более четко с некоторым кодом:

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 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 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

Как вы можете видеть, когда мы изменили элемент класса, он изменился для обоих объектов. Но, когда мы изменили элемент объекта, другой объект остался без изменений.

Ответ 2

Я думаю, что этот пример объясняет разницу между стилями:

[email protected]:~$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
[email protected]:~$./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 привязан к классу, element2 привязан к экземпляру класса.