poprawny sposób definiowania zmiennych klas w Pythonie [duplikat]

Możliwy duplikat:
zmienne wewnątrz i na zewnątrz funkcji klasy __init__ ()

Zauważyłem, że w Pythonie ludzie inicjują swoje atrybuty klas na dwa różne sposoby.

Pierwsza droga jest taka:

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

  def __init__(self):
    #pass or something else

Inny styl wygląda następująco:

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

Jaki jest prawidłowy sposób inicjalizacji atrybutów klasy?

Author: Community, 2012-01-30

2 answers

Oba sposoby nie są poprawne lub niepoprawne, są tylko dwoma różnymi rodzajami elementów klasy:

  • Elementy spoza metody __init__ są elementami statycznymi, to znaczy należą do klasy.
  • elementy wewnątrz metody __init__ są elementami obiektu (self), nie należą do klasy.

Zobaczysz to wyraźniej z jakimś kodem:

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

Jak widzisz, kiedy zmieniliśmy element klasy, zmienił się on dla obu obiektów. Ale kiedy się zmieniliśmy element obiektu, drugi obiekt pozostał niezmieniony.

 408
Author: juliomalegria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-22 06:53:14

Myślę, że ta próbka wyjaśnia różnicę między stylami:

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 jest związany z klasą, element2 jest związany z instancją klasy.
 11
Author: James Polley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-29 22:06:33