__slots__ och minnesoptimering
Använd __slots__ för att minska minnesåtgången per instans.
__slots__ och minnesoptimering är en gratis lektion i Python Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Python Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Python Academy innehåller totalt 4 lektioner.
Den extra kostnaden för standardmässiga __dict__
Som standard lagrar varje Python-instans attribut i en __dict__-ordbok, vilket innebär en betydande minneskostnad – vanligtvis 200–400 byte per instans.
import sys
class Point:
def __init__(self, x, y): self.x, self.y = x, y
p = Point(1, 2)
print(sys.getsizeof(p.__dict__)) # ~200 bytesDeklarera __slots__
Definiera __slots__ som en sekvens av attributnamn. Python allokerar en array med fast storlek i stället för en dict, vilket sparar minne.
class SlottedPoint:
__slots__ = ("x", "y")
def __init__(self, x, y):
self.x = x
self.y = y
p = SlottedPoint(1, 2)
print(p.x, p.y) # 1 2
# p.z = 3 # AttributeError: no __dict__Minnesbesparingar
Med __slots__ sparar varje instans vanligtvis 30–50 % minne jämfört med en dict-baserad instans – en betydande besparing när miljontals objekt skapas.
import sys
class Reg:
def __init__(self, x, y): self.x, self.y = x, y
class Slotted:
__slots__ = ("x","y")
def __init__(self, x, y): self.x, self.y = x, y
print(sys.getsizeof(Reg(1,2))) # ~56 bytes + ~200 dict
print(sys.getsizeof(Slotted(1,2))) # ~56 bytes (no dict)Ingen __dict__ som standard
En klass med slots har ingen __dict__, så det går inte att lägga till godtyckliga attribut efter att instansen har skapats.
class Config:
__slots__ = ("host", "port")
def __init__(self, h, p): self.host, self.port = h, p
c = Config("localhost", 8080)
# c.debug = True # AttributeError
print(hasattr(c, "__dict__")) # FalseBehålla __dict__ med __slots__
Inkludera "__dict__" i __slots__ för att behålla en dict per instans och samtidigt fördeklarera vanliga attribut som slots.
class Hybrid:
__slots__ = ("x", "__dict__")
def __init__(self, x):
self.x = x
h = Hybrid(1)
h.extra = "dynamic" # allowed
print(h.extra)__weakref__ i __slots__
Klasser med slots förlorar stöd för svaga referenser. Lägg till "__weakref__" i __slots__ för att aktivera stödet igen.
import weakref
class Node:
__slots__ = ("value", "__weakref__")
def __init__(self, v): self.value = v
n = Node(42)
ref = weakref.ref(n)
print(ref()) # <Node object>Arv och __slots__
Om en överordnad klass inte använder __slots__ får den underordnade klassen ändå en __dict__. För fullständig besparing måste hela hierarkin definiera __slots__.
class Base:
__slots__ = ("x",)
class Child(Base):
__slots__ = ("y",) # no __dict__
class WithoutSlots(Base):
pass # gets __dict__ from objectMäta minnesanvändning
Använd tracemalloc eller pympler för att mäta den faktiska minnesanvändningen före och efter att __slots__ har lagts till.
import tracemalloc
tracemalloc.start()
points = [SlottedPoint(i, i) for i in range(100_000)]
current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
print(f"Peak: {peak/1024/1024:.1f} MB")__slots__ och pickling
Objekt med slots kan serialiseras med pickle om ni definierar __getstate__ och __setstate__, eller använder standardprotokollet för pickle, som hanterar slots automatiskt från och med Python 3.
import pickle
class Point:
__slots__ = ("x", "y")
def __init__(self, x, y): self.x, self.y = x, y
p = Point(3, 4)
data = pickle.dumps(p)
p2 = pickle.loads(data)
print(p2.x, p2.y) # 3 4dataclasses med __slots__ – Python 3.10+
Skicka slots=True till @dataclass för att automatiskt generera __slots__.
from dataclasses import dataclass
@dataclass(slots=True)
class Vector:
x: float
y: float
v = Vector(1.0, 2.0)
print(v.x, v.y) # 1.0 2.0
print(hasattr(v, "__dict__")) # FalseNär ska __slots__ användas?
Använd __slots__ när ni skapar miljontals instanser, när minnet är begränsat eller när attributåtkomstens hastighet är avgörande. Hoppa över det för klasser för allmän användning där flexibilitet är viktigare.
# Good candidates:
# - Nodes in a large graph or tree
# - Records in a large dataset
# - High-frequency event objects
# Bad candidates:
# - Configuration objects added to ad-hoc
# - Classes that mix-in dynamic attributesSnabbkontroll
Vad händer när ni försöker ange ett attribut som inte finns med i __slots__ för en instans med slots?
Sammanfattning
__slots__ ersätter instansens __dict__ med en array med fast storlek, vilket sparar 30–50 % minne. Inkludera "__dict__" eller "__weakref__" om ni behöver dem. Hela arvskedjan måste använda __slots__ för fullständig besparing. I Python 3.10+ kan ni använda @dataclass(slots=True).
Lär dig Python med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 76
- Lektioner
- 320
Vanliga frågor
Är lektionen ”__slots__ och minnesoptimering” gratis?
Ja – hela texten till ”__slots__ och minnesoptimering” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Python Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Python Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”__slots__ och minnesoptimering”?
Använd __slots__ för att minska minnesåtgången per instans. Ni övar på Python Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Python Academy?
Du behöver inga förkunskaper. Utbildningen i Python Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”__slots__ och minnesoptimering”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Python Academy-lektionen?
Ja. Varje Python Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Hur Python-klasser skapas
- Skriva egna metaklasser
- Deskriptorer: __get__, __set__, __delete__
- __slots__ och minnesoptimering