Issue27933
Created on 2016-09-01 16:08 by Федор Лянгузов, last changed 2022-04-11 14:58 by admin. This issue is now closed.
Files |
|
|
|
File name |
Uploaded |
Description |
Edit |
lru_cache_test.py |
Федор Лянгузов,2016-09-01 16:08 |
3 tests of functools.lru_cache with one failing |
|
Messages (4) |
|
|
msg274149 - (view) |
Author: Федор Лянгузов (Федор Лянгузов) * |
Date: 2016-09-01 16:08 |
Greetings, I've encountered strange behavior when using functools.lru_cache as a function (not as a decorator): it is at least miscounting misses, but probably not work at all, when the result of functools.lru_cache()(func) is saved in variable other than 'func'. Consider this snippet: def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) f = functools.lru_cache()(factorial) f(20) print(f.cache_info()) Output should be: CacheInfo(hits=0, misses=21, maxsize=128, currsize=21) Instead it is: CacheInfo(hits=0, misses=1, maxsize=128, currsize=1) I'm using Python 3.5.2 64bit on Windows 7 Professional 64bit. I've written 3 unittests (using built-in module), which are attached as a file. I don't know how to comment them (conceptually, not syntactically), sorry. Fedor |
|
|
msg274151 - (view) |
Author: Steven D'Aprano (steven.daprano) *  |
Date: 2016-09-01 16:35 |
This behaviour is expected. The factorial function calls itself, it doesn't call "f", but it is "f" which has the cache. So the call to f() goes through the cache, misses, and then calls factorial(), which has no cache. In effect, what you have written is something like: def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) def f(n): if n in f.cache: return f.cache[n] else: x = f.cache[n] = factorial(n) return x f.cache = lru_cache() |
|
|
msg274152 - (view) |
Author: Steven D'Aprano (steven.daprano) *  |
Date: 2016-09-01 16:39 |
In case it isn't obvious, my example is meant to be pseudo-code, not the exact implementation used. |
|
|
msg274167 - (view) |
Author: Федор Лянгузов (Федор Лянгузов) * |
Date: 2016-09-01 18:44 |
Ok, thank you very much, i've got a little smarter today. Now i understand, that user_function (in this case factorial) is not modified by decorator, it is my job to change factorial to wrapper by assignment. Enlightning. |
|
|
History |
|
|
|
Date |
User |
Action |
Args |
2022-04-11 14:58:35 |
admin |
set |
github: 72120 |
2016-09-01 18:44:15 |
Федор Лянгузов |
set |
status: open -> closedresolution: not a bugmessages: + |
2016-09-01 16:39:53 |
steven.daprano |
set |
messages: + |
2016-09-01 16:35:53 |
steven.daprano |
set |
nosy: + steven.dapranomessages: + |
2016-09-01 16:25:32 |
abarry |
set |
nosy: + rhettinger, ncoghlan |
2016-09-01 16:08:44 |
Федор Лянгузов |
create |
|