Python Academy · Oppitunti

functools: lru_cache ja cached_property

Välimuistittakaa raskaita laskutoimituksia lru_cache- ja cached_property-toiminnoilla.

Oppitunti 4/413 vaihetta

functools: lru_cache ja cached_property on ilmainen Python Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Python Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mitä memoisaatio on

Memoisointi tallentaa funktiokutsun tuloksen sen argumenttien muodostaman avaimen perusteella. Samoilla argumenteilla tehdyt toistuvat kutsut palauttavat tallennetun tuloksen välittömästi.

def slow_fib(n):
    if n < 2: return n
    return slow_fib(n-1) + slow_fib(n-2)

# slow_fib(35) makes ~29 million calls
# With caching it makes only 35

@lru_cache

@functools.lru_cache(maxsize=128) tallentaa välimuistiin enintään maxsize viimeisintä tulosta. Asettakaa maxsize=None, jos haluatte rajoittamattoman välimuistin.

import functools

@functools.lru_cache(maxsize=None)
def fib(n):
    if n < 2: return n
    return fib(n-1) + fib(n-2)

print(fib(50))  # instant

@cache — Python 3.9+

functools.cache on lyhyt muoto ilmaisulle lru_cache(maxsize=None) — rajoittamaton välimuisti selkeämmällä nimellä.

import functools

@functools.cache
def factorial(n):
    return n * factorial(n-1) if n else 1

print(factorial(10))  # 3628800

Välimuistin tiedot ja tyhjennys

Välimuistitetut funktiot tarjoavat metodit .cache_info() (osumat, hudit ja koko) ja .cache_clear().

import functools

@functools.lru_cache(maxsize=100)
def square(n):
    return n * n

for i in range(5): square(i % 3)
print(square.cache_info())
# CacheInfo(hits=2, misses=3, maxsize=100, currsize=3)
square.cache_clear()

LRU-poistokäytäntö

LRU (Least Recently Used) poistaa välimuistin ollessa täynnä alkion, jota on käytetty vähiten äskettäin.

import functools

@functools.lru_cache(maxsize=3)
def compute(n):
    print(f"computing {n}")
    return n**2

for x in [1,2,3,4,1]:   # 4 evicts 1 (LRU), then 1 re-computes
    compute(x)

Vain hajautettavat argumentit

lru_cache edellyttää, että kaikki argumentit ovat hajautettavia. Listat ja sanakirjat eivät ole hajautettavia, joten käyttäkää niiden sijaan tuplia.

import functools

@functools.lru_cache(maxsize=None)
def sum_tuple(t):  # tuple is hashable
    return sum(t)

print(sum_tuple((1,2,3)))  # 6
# sum_tuple([1,2,3])  # TypeError

@cached_property

functools.cached_property laskee ominaisuuden kerran ja tallentaa tuloksen instanssiin korvaten deskriptorin arvolla.

import functools

class Circle:
    def __init__(self, r):
        self.r = r

    @functools.cached_property
    def area(self):
        import math
        print("computing...")
        return math.pi * self.r ** 2

c = Circle(5)
print(c.area)   # computing...  78.53...
print(c.area)   # 78.53... (cached, no print)

cached_property vai property

@property laskee arvon uudelleen jokaisella käyttökerralla. @cached_property laskee sen kerran ja tallentaa tuloksen kohteeseen instance.__dict__.

import functools

class Expensive:
    @property
    def always(self):    # runs every access
        return sum(range(1_000_000))

    @functools.cached_property
    def once(self):      # runs only first access
        return sum(range(1_000_000))

cached_propertyn säieturvallisuus

cached_property ei ole säieturvallinen. Jos useat säikeet käyttävät sitä samanaikaisesti, laskenta voidaan suorittaa useammin kuin kerran. Käyttäkää tarvittaessa lukkoa.

import functools, threading

class SafeCache:
    _lock = threading.Lock()

    @functools.cached_property
    def data(self):
        with self._lock:
            return expensive_computation()

cached_propertyn mitätöinti

Poistakaa instanssin attribuutti, jotta välimuisti mitätöityy ja arvo lasketaan uudelleen seuraavalla käyttökerralla.

import functools

class Report:
    @functools.cached_property
    def summary(self):
        return compute_summary()

r = Report()
_ = r.summary      # computed
del r.summary      # invalidate
_ = r.summary      # recomputed

lru_cachen käyttö API-välimuistina

Välimuistittakaa API-vastaukset istunnon ajaksi tarpeettomien verkkokutsujen välttämiseksi. Tyhjentäkää välimuisti, kun tarvitsette ajantasaista dataa.

import functools, urllib.request, json

@functools.lru_cache(maxsize=32)
def get_user(user_id):
    url = f"https://api.example.com/users/{user_id}"
    with urllib.request.urlopen(url) as r:
        return json.loads(r.read())

user = get_user(42)   # network call
user = get_user(42)   # cached

Pikatarkistus

Mikä metodi tyhjentää kaikki @lru_cache-koristellun funktion välimuistitulokset?

Kertaus

@lru_cache tallentaa funktioiden tulokset argumenttien perusteella (argumenttien on oltava hajautettavia). @cache on rajoittamaton alias. @cached_property tallentaa ominaisuuden laskennan tuloksen instanssikohtaisesti. Tarkastelkaa välimuistia komennolla cache_info() ja nollatkaa se komennolla cache_clear().

Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
76
Oppitunnit
320

Usein kysytyt kysymykset

Onko oppitunti ”functools: lru_cache ja cached_property” ilmainen?

Kyllä – oppitunnin ”functools: lru_cache ja cached_property” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Python Academy-kurssin, päivitä CoddyKit PROhon. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”functools: lru_cache ja cached_property”?

Välimuistittakaa raskaita laskutoimituksia lru_cache- ja cached_property-toiminnoilla. Harjoittelet Python Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Python Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Python Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”functools: lru_cache ja cached_property”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Python Academy-oppitunnilla?

Kyllä. Jokainen Python Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. itertools: äärettömät ja äärelliset iteraattorit
  2. itertools: kombinatoriikka
  3. functools: partial ja reduce
  4. functools: lru_cache ja cached_property
← Takaisin: Python Academy