705 votes

Utilisation de __slots__ ?

Quel est le but de __slots__ en Python - notamment en ce qui concerne les cas où je souhaite l'utiliser et ceux où je ne le souhaite pas ?

265voto

Jeff Bauer Points 6598

Citation : Jacob Hallen :

L'utilisation appropriée de __slots__ est d'économiser de l'espace dans les objets. Au lieu d'avoir un dict dynamique qui permet d'ajouter des attributs aux objets à tout moment, il y a une structure statique qui ne permet pas d'ajouts après la création. [Cette utilisation de __slots__ élimine la surcharge d'un dict pour chaque objet]. Bien que ce soit parfois une optimisation utile, elle serait complètement complètement inutile si l'interpréteur Python était suffisamment dynamique pour ne pour n'avoir besoin du dict que lorsqu'il y a effectivement des ajouts à l'objet.

Malheureusement, il y a un effet secondaire aux machines à sous. Ils modifient le comportement des des objets qui ont des slots d'une manière qui peut être abusée par les maniaques du contrôle et les fanatiques du typage statique. C'est mauvais, parce que les maniaques du contrôle devraient contrôle devraient abuser des métaclasses et les fanatiques du typage statique devraient abuser des décorateurs. puisqu'en Python, il ne devrait y avoir qu'une seule façon évidente de faire quelque chose.

Rendre CPython suffisamment intelligent pour gérer l'économie d'espace sans __slots__ est un grand C'est probablement la raison pour laquelle elle ne figure pas (encore) sur la liste des modifications à apporter à P3k.

122voto

Ryan Points 7423

Vous devez utiliser __slots__ si vous avez l'intention d'instancier beaucoup (des centaines, des milliers) d'objets de la même classe. __slots__ n'existe que comme outil d'optimisation de la mémoire.

Il est fortement déconseillé d'utiliser __slots__ pour contraindre la création d'attributs.

Décapage des objets avec __slots__ ne fonctionnera pas avec le protocole pickle par défaut (le plus ancien) ; il est nécessaire de spécifier une version plus récente.

Certaines autres fonctionnalités d'introspection de python peuvent également être affectées.

60voto

Suraj Barkale Points 1482

Chaque objet python possède un __dict__ qui est un dictionnaire contenant tous les autres attributs. Par exemple, lorsque vous tapez self.attr python est en train de faire self.__dict__['attr'] . Comme vous pouvez l'imaginer, l'utilisation d'un dictionnaire pour stocker les attributs prend un peu plus de place et de temps pour y accéder.

Cependant, lorsque vous utilisez __slots__ tout objet créé pour cette classe n'aura pas d'objet de type __dict__ attribut. Au lieu de cela, tous les accès aux attributs se font directement via des pointeurs.

Ainsi, si vous voulez une structure de type C plutôt qu'une classe à part entière, vous pouvez utiliser __slots__ pour compacter la taille des objets et réduire le temps d'accès aux attributs. Un bon exemple est une classe Point contenant les attributs x & y. Si vous avez beaucoup de points, vous pouvez essayer d'utiliser __slots__ afin de conserver un peu de mémoire.

11voto

Demolishun Points 1036

Les slots sont très utiles pour les appels de bibliothèque afin d'éliminer le "named method dispatch" lors des appels de fonction. Ceci est mentionné dans le manuel SWIG documentation . Pour les bibliothèques à haute performance qui veulent réduire la surcharge des fonctions couramment appelées, l'utilisation des slots est beaucoup plus rapide.

Ceci n'est peut-être pas directement lié à la question de l'OP. Il est davantage lié à la construction d'extensions qu'à l'utilisation de l'outil de gestion de l'environnement. Machines à sous sur un objet. Mais cela permet de compléter l'image de l'utilisation des slots et de certains des raisonnements qui les sous-tendent.

1voto

S.Lott Points 207588

Vous n'avez - essentiellement - aucune utilité pour __slots__ .

Pour le moment où vous pensez que vous pourriez avoir besoin __slots__ vous voulez en fait utiliser Léger o Poids plume les modèles de conception. Il s'agit de cas où vous ne souhaitez plus utiliser des objets purement Python. Au lieu de cela, vous voulez une enveloppe de type objet Python autour d'un tableau, d'une structure ou d'un tableau numpy.

class Flyweight(object):

    def get(self, theData, index):
        return theData[index]

    def set(self, theData, index, value):
        theData[index]= value

Le wrapper de type classe n'a pas d'attributs - il fournit simplement des méthodes qui agissent sur les données sous-jacentes. Les méthodes peuvent être réduites à des méthodes de classe. En effet, il pourrait être réduit à de simples fonctions opérant sur le tableau de données sous-jacent.

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