MrFaws Docs
Lær Python

Avanceret

Iterators, generators, decorators, context managers, async og moderne Python-design.

Iterators og generators

En iterable kan levere en iterator. En iterator returnerer værdier én ad gangen og stopper med StopIteration.

def read_chunks(path, size: int = 8192):
    with open(path, "rb") as file:
        while chunk := file.read(size):
            yield chunk

Generators bruger yield og behøver ikke holde alle værdier i hukommelsen samtidig.

Decorators

from functools import wraps
from time import perf_counter

def timed(function):
    @wraps(function)
    def wrapper(*args, **kwargs):
        start = perf_counter()
        try:
            return function(*args, **kwargs)
        finally:
            print(f"{function.__name__}: {perf_counter() - start:.4f}s")
    return wrapper

@timed
def calculate():
    return sum(range(1_000_000))

Decorators er gode til tværgående adfærd som logging, caching og adgangskontrol. De må ikke skjule vigtige sideeffekter.

Context managers

from contextlib import contextmanager

@contextmanager
def transaction(connection):
    try:
        yield connection
        connection.commit()
    except Exception:
        connection.rollback()
        raise

Context managers gør setup og cleanup eksplicit med with.

Async IO

import asyncio

async def worker(name: str, delay: float) -> str:
    await asyncio.sleep(delay)
    return f"{name} færdig"

async def main() -> None:
    results = await asyncio.gather(
        worker("A", 1.0),
        worker("B", 0.5),
    )
    print(results)

asyncio.run(main())

Async passer til mange samtidige ventende operationer som netværk og databaser. Det gør ikke CPU-tung kode hurtigere.

Protocols og dependency injection

from typing import Protocol

class UserStore(Protocol):
    def get_name(self, user_id: int) -> str | None: ...

def greet(user_id: int, store: UserStore) -> str:
    return store.get_name(user_id) or "Ukendt"

Protocol beskriver den adfærd, en dependency skal have, uden at kræve nedarvning.

Packaging

Et moderne bibliotek bruger normalt pyproject.toml, en importérbar package, tests og et tydeligt CLI-entrypoint. Hold runtime-dependencies adskilt fra development-dependencies.

Hvornår er koden avanceret på den gode måde?

  • Abstraktionen fjerner reel gentagelse eller kobling.
  • Fejl og ressource-cleanup er tydelige.
  • Koden kan testes uden netværk eller globale objekter.
  • En simplere løsning er blevet vurderet først.

On this page