Python Academy · Lektion

__slots__ och minnesoptimering

Använd __slots__ för att minska minnesåtgången per instans.

Lektion 4 av 413 steg

__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 bytes

Deklarera __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__"))   # False

Behå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 object

Mä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 4

dataclasses 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__"))   # False

Nä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 attributes

Snabbkontroll

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).

Gratis att börja

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

  1. Hur Python-klasser skapas
  2. Skriva egna metaklasser
  3. Deskriptorer: __get__, __set__, __delete__
  4. __slots__ och minnesoptimering
← Tillbaka till Python Academy