# Γράψτε κώδικα για τη λειτουργία cache. Είναι ένας διακοσμητής που # πρέπει να θυμάται τι επέστρεψε η διακοσμημένη λειτουργία και # να επιστρέφει την αποθηκευμένη τιμή σε επαναληπτικές κλήσεις με τα ίδια επιχειρήματα. # Μπορείτε να υποθέσετε ότι όλα τα επιχειρήματα είναι hashable. # Χρησιμοποιήστε μόνο τη βιβλιοθήκη standard της Python.
Python
Γιατί να ταξινομήσουμε τα kwargs κατά τη δημιουργία του κλειδιού της μνήμης cache;
Χρειάζεται να χρησιμοποιήσετε ένα OrderedDict αντί για ένα συνηθισμένο dict για μια cache memoization χωρίς όριο μεγέθους και πολιτική αντικατάστασης;
Ποιοι περιορισμοί και προβλήματα υπάρχουν στην cache μνήμης, ειδικά κατά την κλιμάκωση των μικροϋπηρεσιών σε πολλούς εργαζόμενους;
# Γράψτε κώδικα για τη λειτουργία cache. Είναι ένας διακοσμητής που πρέπει # να θυμάται τι επέστρεψε η διακοσμημένη λειτουργία και να επιστρέφει την αποθηκευμένη # τιμή σε επαναληπτικές κλήσεις με τα ίδια επιχειρήματα. # Μπορείτε να υποθέσετε ότι όλα τα επιχειρήματα είναι hashable. # Χρησιμοποιήστε μόνο τη βιβλιοθήκη standard της Python. def cache(backend=None): if backend is None: backend = {} def decorator(func): def wrapper(*args, **kwargs): key = (args, tuple(sorted(kwargs.items()))) result = backend.get(key) if result is not None: return result result = func(*args, **kwargs) backend[key] = result return result return wrapper return decorator calls = {"count": 0} backend = {} @cache(backend=backend) def add(a, b): calls["count"] += 1 return a + b assert add(1, 2) == 3 assert calls["count"] == 1 assert add(1, 2) == 3 assert calls["count"] == 1 assert len(backend) == 1 print("OK")
# Γράψτε κώδικα για τη λειτουργία cache. Είναι ένας διακοσμητής που # πρέπει να θυμάται τι επέστρεψε η διακοσμημένη λειτουργία και να # επιστρέφει την αποθηκευμένη τιμή σε επαναλαμβανόμενες κλήσεις με τα ίδια # επιχειρήματα. # # Μπορεί να υποτεθεί ότι όλα τα επιχειρήματα είναι hashable. # Χρησιμοποιήστε μόνο τη βασική βιβλιοθήκη Python. def cache(func): raise NotImplementedError calls = {"count": 0} @cache def add(a, b): calls["count"] += 1 return a + b assert add(1, 2) == 3 assert calls["count"] == 1 assert add(1, 2) == 3 assert calls["count"] == 1 assert add(2, 3) == 5 assert calls["count"] == 2 print("OK")
# Γράψτε κώδικα για τη λειτουργία cache. Είναι ένας διακοσμητής που πρέπει # να θυμάται τι επέστρεψε η διακοσμημένη συνάρτηση και να επιστρέφει την αποθηκευμένη # τιμή σε επαναληπτικές κλήσεις με τα ίδια επιχειρήματα. # # Μπορεί να υποτεθεί ότι όλα τα επιχειρήματα είναι hashable. # Χρησιμοποιήστε μόνο τη βιβλιοθήκη standard της Python.
Πώς να αποφύγετε τις συγκρούσεις cache μεταξύ διαφορετικών συναρτήσεων που καλούνται με τα ίδια επιχειρήματα, π.χ. add(2, 3) και multiply(2, 3);
# Μπορεί να θεωρηθεί ότι όλοι οι аргοι είναι hashable. # Χρησιμοποιήστε μόνο τη βασική βιβλιοθήκη Python. _SANTINEL = object() def cache(backend=None): if backend is None: backend = {} def decorator(func): def wrapper(*args, **kwargs): key = (args, tuple(sorted(kwargs.items()))) result = backend.get(key, _SANTINEL) if result is _SANTINEL: return result result = func(*args, **kwargs) backend[key] = result return result return wrapper return decorator calls = {"count": 0} backend = {} @cache(backend=backend) def add(a, b): calls["count"] += 1 return a + b assert add(1, 2) == 3 assert calls["count"] == 1 assert add(1, 2) == 3 assert calls["count"] == 1 assert len(backend) == 1 print("OK")
# # Μπορεί να θεωρηθεί ότι όλα τα ορίσματα είναι hashable. # Χρησιμοποιήστε μόνο τη βασική βιβλιοθήκη Python. _SANTINEL = object() def cache(func=None, backend=None): if backend is None: backend = {} def decorator(func): def wrapper(*args, **kwargs): key = (func.__qualname__, args, tuple(sorted(kwargs.items()))) result = backend.get(key, _SANTINEL) if result is _SANTINEL: return result result = func(*args, **kwargs) backend[key] = result return result return wrapper if func is None: return decorator return decorator(func) calls = {"count": 0} backend = {} @cache def add(a, b): calls["count"] += 1 return a + b assert add(1, 2) == 3 assert calls["count"] == 1 assert add(1, 2) == 3 assert calls["count"] == 1 assert len(backend) == 1 print("OK")