L'attribut de slots dans Python est un outil utilisé pour déclarer explicitement les attributs de données (variables d'instance) au niveau de la classe, ce qui peut conduire à une utilisation de mémoire plus efficace et à un accès d'attribut plus rapide. Lorsqu'une classe définit un attribut __slots__
, Python crée un petit tableau de taille fixe pour chaque instance de la classe, au lieu d'utiliser un dictionnaire dynamique pour stocker les attributs d'instance. Ce mécanisme sert à plusieurs fins:
__slots__
, le __dict__
de l'instance n'est pas créé, ce qui enregistre la mémoire, en particulier lorsqu'il s'agit d'un grand nombre d'instances.__slots__
peut être plus rapide que l'accès aux attributs dans une instance basée sur le dictionnaire standard, car il évite les frais généraux des recherches de dictionnaire.__slots__
est défini, Python restreint la création de nouveaux attributs dans les cas à ceux définis dans __slots__
, à moins que __dict__
ne soit explicitement inclus dans __slots__
. Voici un exemple de base de la façon d'utiliser __slots__
:
<code class="python">class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y</code>
L'utilisation de __slots__
peut offrir plusieurs avantages de performance:
__slots__
remplace le __dict__
de l'instance par un tableau de taille fixe, il peut réduire considérablement l'empreinte mémoire des instances. Ceci est particulièrement bénéfique lors de la création d'un grand nombre d'instances.__slots__
sont accessibles plus rapidement que ceux stockés dans un dictionnaire. En effet, l'accès à un élément dans un petit tableau de taille fixe est généralement plus rapide que d'effectuer une recherche de dictionnaire.__slots__
peuvent être collectées plus rapidement par le collecteur des ordures car il y a moins de références à suivre.Pour illustrer ces avantages, considérez l'exemple suivant:
<code class="python">import sys class StandardPoint: def __init__(self, x, y): self.x = x self.y = y class SlotPoint: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y standard = StandardPoint(1, 2) slot = SlotPoint(1, 2) print(sys.getsizeof(standard)) # Output may be around 56 bytes print(sys.getsizeof(slot)) # Output may be around 32 bytes</code>
Dans cet exemple, l'instance SlotPoint
utilise moins de mémoire que l'instance StandardPoint
.
L'utilisation de __slots__
affecte l'attribut d'attribut de la manière suivante:
__slots__
est défini, seuls les attributs répertoriés dans __slots__
peuvent être affectés à une instance. Tenter d'attribuer un attribut qui n'est pas dans __slots__
augmentera un AttributeError
, à moins que __dict__
ne soit inclus dans __slots__
.__dict__
automatique : Par défaut, les instances de classes avec __slots__
n'ont pas de __dict__
. Cela signifie que l'attribut dynamique est désactivé à moins que __dict__
ne soit explicitement inclus dans __slots__
.__weakref__
: Si la classe doit prendre en charge les références faibles, __weakref__
doit être inclus dans __slots__
.Voici un exemple pour démontrer ces effets:
<code class="python">class RestrictedPoint: __slots__ = ('x', 'y') point = RestrictedPoint() point.x = 10 # This is allowed point.y = 20 # This is allowed try: point.z = 30 # This will raise an AttributeError except AttributeError as e: print(e) # Output: 'RestrictedPoint' object has no attribute 'z'</code>
Oui, __slots__
peut être utilisé en combinaison avec l'héritage, mais il y a plusieurs considérations à garder à l'esprit:
__slots__
, elle héritera des fentes de sa superclasse, mais seulement si la superclasse définit également __slots__
. Si une superclasse n'utilise pas __slots__
, ses instances utiliseront toujours __dict__
, ce qui peut conduire à des inefficacités de mémoire.__dict__
: Si une sous-classe veut autoriser les attributs dynamiques, il peut inclure __dict__
dans ses __slots__
. Cependant, cela peut vaincre l'objectif d'économie de mémoire d'utiliser __slots__
en premier lieu.__slots__
, toutes les classes doivent définir __slots__
ou hériter d'une classe qui définit __slots__
. Si une classe parent n'utilise pas __slots__
, les instances de la sous-classe auront toujours un __dict__
.Voici un exemple pour illustrer ces considérations:
<code class="python">class Base: __slots__ = ('x',) class Derived(Base): __slots__ = ('y',) # Inherits 'x' from Base derived = Derived() derived.x = 10 # Inherited from Base derived.y = 20 # Defined in Derived class FlexibleDerived(Base): __slots__ = ('y', '__dict__') # Allows dynamic attributes flexible = FlexibleDerived() flexible.x = 10 # Inherited from Base flexible.y = 20 # Defined in FlexibleDerived flexible.z = 30 # Dynamic attribute, allowed because of __dict__</code>
En conclusion, bien que __slots__
puisse être utilisé efficacement avec l'héritage, il nécessite une planification minutieuse pour garantir que l'optimisation de la mémoire et le comportement d'attribut souhaités sont obtenus dans la hiérarchie des classes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!