152 votes

Quelle est la différence entre les attributs de classe et les attributs d'instance ?

Y a-t-il une distinction significative entre:

classe A(objet):
    foo = 5   # une valeur par défaut

vs.

classe B(objet):
    def __init__(self, foo=5):
        self.foo = foo

Si vous créez beaucoup d'instances, y a-t-il une différence de performances ou d'exigences d'espace pour les deux styles? Lorsque vous lisez le code, considérez-vous que la signification des deux styles est significativement différente?

1 votes

Je viens de réaliser qu'une question similaire a été posée et répondue ici: stackoverflow.com/questions/206734/… Dois-je supprimer cette question?

3 votes

C'est votre question, n'hésitez pas à la supprimer. Puisque c'est la vôtre, pourquoi demander l'opinion de quelqu'un d'autre?

0voto

tzot Points 32224

Conformément au commentaire de Dan :

Question similaire qui a été répondue : Pourquoi les références aux attributs agissent de cette façon avec l'héritage en Python

0voto

SimonShyu Points 95

Il y a une autre situation.

Les attributs de classe et d'instance sont Descripteur.

# -*- encoding: utf-8 -*-

class RevealAccess(object):
    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        return self.val

class Base(object):
    attr_1 = RevealAccess(10, 'var "x"')

    def __init__(self):
        self.attr_2 = RevealAccess(10, 'var "x"')

def main():
    b = Base()
    print("Accès à l'attribut de la classe, retour : ", Base.attr_1)
    print("Accès à l'attribut d'instance, retour : ", b.attr_2)

if __name__ == '__main__':
    main()

Le résultat ci-dessus sera affiché :

('Accès à l'attribut de la classe, retour : ', 10)
('Accès à l'attribut d'instance, retour : ', <__main__.RevealAccess object at 0x10184eb50>)

Le même type d'accès à l'instance par l'intermédiaire de la classe ou de l'instance renvoie des résultats différents !

Et j'ai trouvé dans la définition de c.PyObject_GenericGetAttr, et un excellent post.

Expliquer

Si l'attribut est trouvé dans le dictionnaire des classes qui composent l'ordre de résolution de méthodes (MRO) de l'objet, vérifiez si l'attribut recherché pointe vers un Descripteur de données (qui n'est rien de plus qu'une classe implémentant à la fois les méthodes __get__ et __set__). Si c'est le cas, résolvez la recherche de l'attribut en appelant la méthode __get__ du Descripteur de données (lignes 28–33).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X