MrFaws Docs
Lær Python

Svære emner

Descriptors, MRO, metaclasses, hukommelse, GIL, multiprocessing og performance.

Object model og descriptors

Metoder, property, classmethod og mange frameworks bygger på descriptor-protokollen: __get__, __set__ og __delete__.

class Positive:
    def __set_name__(self, owner, name):
        self.name = name

    def __get__(self, instance, owner):
        if instance is None:
            return self
        return instance.__dict__[self.name]

    def __set__(self, instance, value):
        if value <= 0:
            raise ValueError("Skal være positiv")
        instance.__dict__[self.name] = value

Brug normalt property eller dataclasses. Skriv kun egne descriptors, når samme feltadfærd skal genbruges på mange klasser.

MRO og multiple inheritance

Python bruger C3 linearization til Method Resolution Order.

print(MyClass.mro())

Kooperativ nedarvning kræver, at alle klasser bruger super() kompatibelt. Mixins bør være små og have ét formål.

Metaclasses

En metaclass styrer oprettelsen af klasser, ligesom en klasse styrer oprettelsen af objekter. Typiske anvendelser er registrering, validering og framework-infrastruktur.

Vælg den mindst magiske løsning

En decorator, factory eller __init_subclass__ er ofte lettere at forstå end en metaclass.

Hukommelse

CPython bruger reference counting og en cyclic garbage collector. del fjerner en reference, ikke nødvendigvis objektet med det samme.

Brug generators til streaming, __slots__ kun efter måling, og undgå ubegrænsede caches.

GIL og parallelisme

  • Threads er nyttige til blokkerende IO.
  • asyncio er nyttigt til mange koordinerede IO-operationer.
  • Processes er typisk valget til CPU-tung Python-kode.
  • Native biblioteker kan frigive GIL og arbejde parallelt internt.

Vælg model efter workload, ikke efter hvilken API der ser nemmest ud.

Performance

Mål før optimering:

python -m cProfile -s cumulative app.py
python -m timeit "sum(range(1000))"

Prioritér algoritmer, færre database- eller netværkskald og streaming før mikrooptimeringer.

Robust arkitektur

Adskil domænelogik fra IO. Lad kernefunktioner modtage almindelige værdier og returnere resultater. Placér database, HTTP, Discord og filsystem i adapters omkring kernen.

For svære systemer bør du kunne svare på:

  1. Hvem ejer tilstanden?
  2. Hvad sker der ved delvis fejl?
  3. Kan operationen køres igen sikkert?
  4. Hvor logges og måles fejl?
  5. Hvordan testes det uden produktionssystemer?

On this page