Mau*_*ice 11 python caching python-3.x
我试图用来functools.lru_cache缓存内部函数的结果,但缓存似乎没有按预期工作。
我有一个函数执行一些逻辑,然后调用一个相当昂贵的函数。我想缓存昂贵的函数调用的结果,尽管我只是将其应用于lru_cache内部函数。不幸的是,行为并不符合预期——即使内部函数的参数相同,每次都会调用昂贵的函数。
我创建了一个(简化的)测试用例来显示行为:
import unittest
from functools import lru_cache
from unittest.mock import patch
def expensive_function(parameter: str) -> str:
return parameter
def partially_cached(some_parameter: str) -> str:
@lru_cache
def inner_function(parameter: str):
return expensive_function(parameter)
result = inner_function(some_parameter)
print(inner_function.cache_info())
return result
class CacheTestCase(unittest.TestCase):
def test_partially_cached(self):
with patch(self.__module__ + ".expensive_function") as expensive_mock:
expensive_mock.return_value = "a"
self.assertEqual(partially_cached("a"), "a")
self.assertEqual(partially_cached("a"), "a")
# If the cache works, I expect the expensive function
# to be called just once for the same parameter
expensive_mock.assert_called_once()
if __name__ == "__main__":
unittest.main()
Run Code Online (Sandbox Code Playgroud)
(在这种情况下,我不需要内部函数,但正如我所说 - 它被简化了)
不幸的是测试失败了
python3 /scratch/test_cache.py
CacheInfo(hits=0, misses=1, maxsize=128, currsize=1)
CacheInfo(hits=0, misses=1, maxsize=128, currsize=1)
F
======================================================================
FAIL: test_partially_cached (__main__.CacheTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
[...]
AssertionError: Expected 'expensive_function' to have been called once. Called 2 times.
Calls: [call('a'), call('a')].
----------------------------------------------------------------------
Ran 1 test in 0.004s
FAILED (failures=1)
Run Code Online (Sandbox Code Playgroud)
我可能对内部函数或 lru_cache 有误解,但我不确定它是什么 - 我感谢我能得到的所有帮助。
它无法按预期工作,因为inner_function每次partially_cached调用时都会重新定义 gets ,缓存版本也是如此。因此每个缓存版本仅被调用一次。
请参阅memoizing-decorator-keeping-stored-values
此外,如果您模拟装饰函数,则需要再次应用装饰器。
请参阅如何模拟装饰函数
如果您在外部级别进行装饰,或者装饰另一个提取到外部级别的函数,如果您不通过模拟破坏它,它将起作用。
| 归档时间: |
|
| 查看次数: |
2722 次 |
| 最近记录: |