web-dev-qa-db-fra.com

bonne façon de définir les variables de classe dans Python

Duplicate possible:
Variables à l'intérieur et à l'extérieur d'une classe __init __ ()

J'ai remarqué qu'en Python, les gens initialisent leurs attributs de classe de deux manières différentes.

La première façon est comme ça:

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

  def __init__(self):
    #pass or something else

L'autre style ressemble à:

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

Quelle est la bonne façon d'initialiser les attributs de classe?

221
jeanc

Aucune solution n'est nécessairement correcte ou incorrecte, il ne s'agit que de deux types différents d'éléments de classe:

  • Les éléments extérieurs à la méthode __init__ sont des éléments statiques. ils appartiennent à la classe.
  • Les éléments de la méthode __init__ sont des éléments de l'objet (self); ils n'appartiennent pas à la classe.

Vous le verrez plus clairement avec du 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

Comme vous pouvez le constater, l’élément de classe a été modifié pour les deux objets. Mais, lorsque nous avons changé l'élément d'objet, l'autre objet est resté inchangé.

503
juliomalegria

Je pense que cet exemple explique la différence entre les 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 est lié à la classe, element2 est lié à une instance de la classe.

14
James Polley