Tom*_*ale 5 python caching lru functools
给出函数定义的文档lru_cache:
Run Code Online (Sandbox Code Playgroud)@functools.lru_cache(maxsize=128, typed=False)
这对我说maxsize是可选的.
但是,它不喜欢没有参数调用:
Python 3.6.3 (default, Oct 24 2017, 14:48:20)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import functools
>>> @functools.lru_cache
... def f(): ...
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/functools.py", line 477, in lru_cache
raise TypeError('Expected maxsize to be an integer or None')
TypeError: Expected maxsize to be an integer or None
>>>
Run Code Online (Sandbox Code Playgroud)
使用参数调用很好:
>>> @functools.lru_cache(8)
... def f(): ...
...
>>>
Run Code Online (Sandbox Code Playgroud)
我误读了文档吗?
Bor*_*ris 13
Starting with Python 3.8+ you can use @lru_cache without parentheses, so your code snippet will work as-is
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 9.2.1 20191008] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import functools
>>> @functools.lru_cache
... def f():
... return 2
...
>>>
Run Code Online (Sandbox Code Playgroud)
On older versions of Python (i.e. 3.7 or below) you have to do @lru_cache(). As in, add parentheses after @lru_cache
PS. @lru_cache with no arguments implicitly sets max_size to 128. If you want to use a cache with no max size instead, on Python 3.9 you can use the new functools.cache decorator, which acts like lru_cache(max_size=None).
Céd*_*ien 10
你必须至少调用没有args的lru_cache:
@lru_cache()
def f():
#content of the function
Run Code Online (Sandbox Code Playgroud)
这样,lru_cache就会使用默认参数进行初始化.
这是因为python中的装饰器(带@符号)是特殊函数,在解析器读取源时会对其进行求值和调用.
当你写的时候@decorator_name告诉python这decorator_name是一个将使用之后定义的函数(或类)调用的函数.例:
@my_decorator
def function():
pass
Run Code Online (Sandbox Code Playgroud)
相当于:
def function():
pass
decorated_function = my_decorator(function)
Run Code Online (Sandbox Code Playgroud)
该lru_cache装饰是更复杂一点,因为包装的功能之前,必须创建高速缓存(相关功能),然后用另一个函数,将做缓存管理包的功能.这是CPython实现的(简短)代码:
def lru_cache(maxsize=128, typed=False):
# first, there is a test about the type of the parameters
if maxsize is not None and not isinstance(maxsize, int):
raise TypeError('Expected maxsize to be an integer or None')
# then, the decorating function is created, this function will be called each time you'll call the 'cached' function
def decorating_function(user_function):
wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) # in _lru_wrapper is all the magic about the cache management, it is a 2nd layer of decorator
return update_wrapper(wrapper, user_function)
return decorating_function
Run Code Online (Sandbox Code Playgroud)
所以,当你只写时
@lru_cache
def f():
Run Code Online (Sandbox Code Playgroud)
python被称为lru_cache(f),并且最终,它没有被处理这样的事情.
为了使其符合此写入,我们应该添加一个测试来检查第一个参数(maxsize)是否是可调用函数:
def lru_cache(maxsize=128, typed=False):
# first, there is a test about the type of the parameters
if callable(maxsize):
def decorating_function(user_function):
wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
return update_wrapper(wrapper, user_function)
return decorating_function(maxsize) # yes, maxsizeis the function in this case O:)
if maxsize is not None and not isinstance(maxsize, int):
raise TypeError('Expected maxsize to be an integer or None')
# then, the decorating function is created, this function will be called each time you'll call the 'cached' function
def decorating_function(user_function):
wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) # in _lru_wrapper is all the magic about the cache management, it is a 2nd layer of decorator
return update_wrapper(wrapper, user_function)
return decorating_function
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2495 次 |
| 最近记录: |