Python Academy · Lektion

__slots__ og hukommelsesoptimering

Brug __slots__ til at reducere hukommelsesforbruget pr. instans.

Lektion 4 af 413 trin

__slots__ og hukommelsesoptimering er en gratis Python Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Python Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Python Academy-kurset indeholder 4 lektioner i alt.

Standardoverhead for __dict__

Som standard gemmer hver Python-instans attributter i en __dict__-ordbog, hvilket giver et betydeligt hukommelsesoverhead — typisk 200-400 byte pr. 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

Deklaration af __slots__

Definér __slots__ som en sekvens af attributnavne. Python allokerer et array med fast størrelse i stedet for en dict, så du sparer hukommelse.

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__

Hukommelsesbesparelse

Med __slots__ bruger hver instans typisk 30-50 % mindre hukommelse end en dict-baseret instans — en betydelig besparelse, når du opretter millioner af objekter.

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 klasse med slots har ingen __dict__, så du kan ikke tilføje vilkårlige attributter efter oprettelsen.

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

Bevar __dict__ med __slots__

Inkludér "__dict__" i __slots__ for at bevare en dict pr. instans, samtidig med at du forhåndsdeklarerer almindelige attributter 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 mister understøttelse af weak references. Tilføj "__weakref__" til __slots__ for at aktivere understøttelsen 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>

Nedarvning og __slots__

Hvis en parentklasse ikke bruger __slots__, får childklassen stadig en __dict__. For at opnå den fulde besparelse skal hele hierarkiet definere __slots__.

class Base:
    __slots__ = ("x",)

class Child(Base):
    __slots__ = ("y",)   # no __dict__

class WithoutSlots(Base):
    pass   # gets __dict__ from object

Måling af hukommelse

Brug tracemalloc eller pympler til at måle det faktiske hukommelsesforbrug før og efter tilføjelsen af __slots__.

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__ og pickling

Objekter med slots kan pickles, hvis du definerer __getstate__ og __setstate__, eller bruger standardprotokollen for pickle, som automatisk håndterer slots fra 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+

Videregiv slots=True til @dataclass for automatisk at generere __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

Hvornår skal du bruge __slots__

Brug __slots__, når du opretter millioner af instanser, når hukommelsen er begrænset, eller når hastigheden for attributadgang er kritisk. Undlad det i klasser til generelle formål, hvor fleksibilitet er vigtigere.

# 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

Hurtigt tjek

Hvad sker der, når du forsøger at sætte en attribut, der ikke står i __slots__, på en instans med slots?

Opsummering

__slots__ erstatter instansens __dict__ med et array med fast størrelse, så du sparer 30-50 % hukommelse. Inkludér "__dict__" eller "__weakref__", hvis du har brug for dem. Hele nedarvningskæden skal bruge __slots__ for at opnå den fulde besparelse. I Python 3.10+ kan du bruge @dataclass(slots=True).

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
76
Lektioner
320

Ofte stillede spørgsmål

Er lektionen “__slots__ og hukommelsesoptimering” gratis?

Ja — hele teksten til “__slots__ og hukommelsesoptimering” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Python Academy-kurset, skal du opgradere til CoddyKit PRO. Python Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “__slots__ og hukommelsesoptimering”?

Brug __slots__ til at reducere hukommelsesforbruget pr. instans. Du øver dig i Python Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Python Academy?

Der kræves ingen tidligere erfaring. Python Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “__slots__ og hukommelsesoptimering”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Python Academy-lektion?

Ja. Alle Python Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Sådan oprettes Python-klasser
  2. Skrivning af brugerdefinerede metaklasser
  3. Deskriptorer: __get__, __set__, __delete__
  4. __slots__ og hukommelsesoptimering
← Tilbage til Python Academy