Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
c79fb0e5
Kaydet (Commit)
c79fb0e5
authored
Ara 01, 2010
tarafından
Raymond Hettinger
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue 10593: Adopt Nick's suggestion for an lru_cache with maxsize=None.
üst
ed3a7d2d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
25 deletions
+78
-25
functools.rst
Doc/library/functools.rst
+23
-6
functools.py
Lib/functools.py
+41
-19
test_functools.py
Lib/test/test_functools.py
+14
-0
No files found.
Doc/library/functools.rst
Dosyayı görüntüle @
c79fb0e5
...
@@ -32,7 +32,7 @@ The :mod:`functools` module defines the following functions:
...
@@ -32,7 +32,7 @@ The :mod:`functools` module defines the following functions:
A compare function is any callable that accept two arguments, compares them,
A compare function is any callable that accept two arguments, compares them,
and returns a negative number for less-than, zero for equality, or a positive
and returns a negative number for less-than, zero for equality, or a positive
number for greater-than. A key function is a callable that accepts one
number for greater-than. A key function is a callable that accepts one
argument and returns another value
that indicates
the position in the desired
argument and returns another value
indicating
the position in the desired
collation sequence.
collation sequence.
Example::
Example::
...
@@ -51,10 +51,14 @@ The :mod:`functools` module defines the following functions:
...
@@ -51,10 +51,14 @@ The :mod:`functools` module defines the following functions:
Since a dictionary is used to cache results, the positional and keyword
Since a dictionary is used to cache results, the positional and keyword
arguments to the function must be hashable.
arguments to the function must be hashable.
If *maxsize* is set to None, the LRU feature is disabled and the cache
can grow without bound.
To help measure the effectiveness of the cache and tune the *maxsize*
To help measure the effectiveness of the cache and tune the *maxsize*
parameter, the wrapped function is instrumented with a :func:`cache_info`
parameter, the wrapped function is instrumented with a :func:`cache_info`
function that returns a :term:`named tuple` showing *hits*, *misses*,
function that returns a :term:`named tuple` showing *hits*, *misses*,
*maxsize* and *currsize*.
*maxsize* and *currsize*. In a multi-threaded environment, the hits
and misses are approximate.
The decorator also provides a :func:`cache_clear` function for clearing or
The decorator also provides a :func:`cache_clear` function for clearing or
invalidating the cache.
invalidating the cache.
...
@@ -89,12 +93,25 @@ The :mod:`functools` module defines the following functions:
...
@@ -89,12 +93,25 @@ The :mod:`functools` module defines the following functions:
>>> print(get_pep.cache_info())
>>> print(get_pep.cache_info())
CacheInfo(hits=3, misses=8, maxsize=20, currsize=8)
CacheInfo(hits=3, misses=8, maxsize=20, currsize=8)
.. versionadded:: 3.2
Example of efficiently computing
`Fibonacci numbers <http://en.wikipedia.org/wiki/Fibonacci_number>`_
using a cache to implement a
`dynamic programming <http://en.wikipedia.org/wiki/Dynamic_programming>`_
technique::
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
.. seealso::
>>> print([fib(n) for n in range(16)])
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
Recipe for a `plain cache without the LRU feature
>>> print(fib.cache_info())
<http://code.activestate.com/recipes/577479-simple-caching-decorator/>`_.
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
.. versionadded:: 3.2
.. decorator:: total_ordering
.. decorator:: total_ordering
...
...
Lib/functools.py
Dosyayı görüntüle @
c79fb0e5
...
@@ -119,6 +119,9 @@ _CacheInfo = namedtuple("CacheInfo", "hits misses maxsize currsize")
...
@@ -119,6 +119,9 @@ _CacheInfo = namedtuple("CacheInfo", "hits misses maxsize currsize")
def
lru_cache
(
maxsize
=
100
):
def
lru_cache
(
maxsize
=
100
):
"""Least-recently-used cache decorator.
"""Least-recently-used cache decorator.
If *maxsize* is set to None, the LRU features are disabled and the cache
can grow without bound.
Arguments to the cached function must be hashable.
Arguments to the cached function must be hashable.
View the cache statistics named tuple (hits, misses, maxsize, currsize) with
View the cache statistics named tuple (hits, misses, maxsize, currsize) with
...
@@ -136,32 +139,51 @@ def lru_cache(maxsize=100):
...
@@ -136,32 +139,51 @@ def lru_cache(maxsize=100):
def
decorating_function
(
user_function
,
def
decorating_function
(
user_function
,
tuple
=
tuple
,
sorted
=
sorted
,
len
=
len
,
KeyError
=
KeyError
):
tuple
=
tuple
,
sorted
=
sorted
,
len
=
len
,
KeyError
=
KeyError
):
cache
=
OrderedDict
()
# ordered least recent to most recent
cache_popitem
=
cache
.
popitem
cache_renew
=
cache
.
move_to_end
hits
=
misses
=
0
hits
=
misses
=
0
kwd_mark
=
object
()
# separates positional and keyword args
kwd_mark
=
object
()
# separates positional and keyword args
lock
=
Lock
()
lock
=
Lock
()
@wraps
(
user_function
)
if
maxsize
is
None
:
def
wrapper
(
*
args
,
**
kwds
):
cache
=
dict
()
# simple cache without ordering or size limit
nonlocal
hits
,
misses
key
=
args
@wraps
(
user_function
)
if
kwds
:
def
wrapper
(
*
args
,
**
kwds
):
key
+=
(
kwd_mark
,)
+
tuple
(
sorted
(
kwds
.
items
()))
nonlocal
hits
,
misses
try
:
key
=
args
with
lock
:
if
kwds
:
key
+=
(
kwd_mark
,)
+
tuple
(
sorted
(
kwds
.
items
()))
try
:
result
=
cache
[
key
]
result
=
cache
[
key
]
cache_renew
(
key
)
# record recent use of this key
hits
+=
1
hits
+=
1
except
KeyError
:
except
KeyError
:
result
=
user_function
(
*
args
,
**
kwds
)
result
=
user_function
(
*
args
,
**
kwds
)
with
lock
:
cache
[
key
]
=
result
cache
[
key
]
=
result
# record recent use of this key
misses
+=
1
misses
+=
1
if
len
(
cache
)
>
maxsize
:
return
result
cache_popitem
(
0
)
# purge least recently used cache entry
else
:
return
result
cache
=
OrderedDict
()
# ordered least recent to most recent
cache_popitem
=
cache
.
popitem
cache_renew
=
cache
.
move_to_end
@wraps
(
user_function
)
def
wrapper
(
*
args
,
**
kwds
):
nonlocal
hits
,
misses
key
=
args
if
kwds
:
key
+=
(
kwd_mark
,)
+
tuple
(
sorted
(
kwds
.
items
()))
try
:
with
lock
:
result
=
cache
[
key
]
cache_renew
(
key
)
# record recent use of this key
hits
+=
1
except
KeyError
:
result
=
user_function
(
*
args
,
**
kwds
)
with
lock
:
cache
[
key
]
=
result
# record recent use of this key
misses
+=
1
if
len
(
cache
)
>
maxsize
:
cache_popitem
(
0
)
# purge least recently used cache entry
return
result
def
cache_info
():
def
cache_info
():
"""Report cache statistics"""
"""Report cache statistics"""
...
...
Lib/test/test_functools.py
Dosyayı görüntüle @
c79fb0e5
...
@@ -586,6 +586,20 @@ class TestLRU(unittest.TestCase):
...
@@ -586,6 +586,20 @@ class TestLRU(unittest.TestCase):
self
.
assertEqual
(
misses
,
4
)
self
.
assertEqual
(
misses
,
4
)
self
.
assertEqual
(
currsize
,
2
)
self
.
assertEqual
(
currsize
,
2
)
def
test_lru_with_maxsize_none
(
self
):
@functools.lru_cache
(
maxsize
=
None
)
def
fib
(
n
):
if
n
<
2
:
return
n
return
fib
(
n
-
1
)
+
fib
(
n
-
2
)
self
.
assertEqual
([
fib
(
n
)
for
n
in
range
(
16
)],
[
0
,
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
,
144
,
233
,
377
,
610
])
self
.
assertEqual
(
fib
.
cache_info
(),
functools
.
_CacheInfo
(
hits
=
28
,
misses
=
16
,
maxsize
=
None
,
currsize
=
16
))
fib
.
cache_clear
()
self
.
assertEqual
(
fib
.
cache_info
(),
functools
.
_CacheInfo
(
hits
=
0
,
misses
=
0
,
maxsize
=
None
,
currsize
=
0
))
def
test_main
(
verbose
=
None
):
def
test_main
(
verbose
=
None
):
test_classes
=
(
test_classes
=
(
TestPartial
,
TestPartial
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment