为什么 'functools.cache' 和 'functools.lru_cache' 不适用于 class 方法中的内部函数?
Why does 'functools.cache' and 'functools.lru_cache' not working for inner function inside class method?
为什么 functools.cache
和 functools.lru_cache
不适用于 class 方法中的内部函数?在不安装 3rd 方包并且不将内部函数移动到外部范围的情况下是否有任何解决方法?
from functools import cache
class Sample:
def outer(self, a):
@cache
def inner(b):
print(f"Inner function is called! b: '{b}'")
return b
return inner(a)
sample = Sample()
sample.outer(100)
sample.outer(100)
sample.outer(100)
输出:
Inner function is called! b: '100'
Inner function is called! b: '100'
Inner function is called! b: '100'
我希望内部函数对同一个参数只调用一次。
据推测,每次调用 outer
时,inner
函数都会获取“re-created”,导致缓存不再起作用。这个例子证实了这一点,它从 outer
:
多次调用 inner
from functools import cache
class Sample:
def outer(self, a):
@cache
def inner(b):
print(f"Inner function is called! b: '{b}'")
return b
for i in range(3):
print(f"Inner call #{i}")
print(inner(a))
return
sample = Sample()
sample.outer(100)
sample.outer(100)
sample.outer(100)
输出:
Inner call #0
Inner function is called! b: '100'
100
Inner call #1
100
Inner call #2
100
Inner call #0
Inner function is called! b: '100'
100
Inner call #1
100
Inner call #2
100
Inner call #0
Inner function is called! b: '100'
100
Inner call #1
100
Inner call #2
100
因此,缓存 确实 起作用,但仅在 inner
class 为“re-created” 之前有效。一个非常简单的解决方案是避免使用内部函数,而是依赖以下静态函数:
from functools import cache
class Sample:
@staticmethod
@cache
def _inner(b):
print(f"Inner function is called! b: '{b}'")
return b
def outer(self, a):
for i in range(3):
print(f"Inner call #{i}")
print(Sample._inner(a))
return
sample = Sample()
sample.outer(100)
sample.outer(100)
sample.outer(100)
请注意,我已将 inner
重命名为 _inner
,以表明 _inner
不打算暴露给 class 的用户。此外,我把它变成了静态方法。这允许您使用 Sample._inner(...)
而不是 self._inner(...)
。毕竟self
参数没有在_inner
中使用,所以可以是静态函数
这输出(期望的):
Inner call #0
Inner function is called! b: '100'
100
Inner call #1
100
Inner call #2
100
Inner call #0
100
Inner call #1
100
Inner call #2
100
Inner call #0
100
Inner call #1
100
Inner call #2
100
这表明已为不同的 outer
调用正确缓存所有内容。
为什么 functools.cache
和 functools.lru_cache
不适用于 class 方法中的内部函数?在不安装 3rd 方包并且不将内部函数移动到外部范围的情况下是否有任何解决方法?
from functools import cache
class Sample:
def outer(self, a):
@cache
def inner(b):
print(f"Inner function is called! b: '{b}'")
return b
return inner(a)
sample = Sample()
sample.outer(100)
sample.outer(100)
sample.outer(100)
输出:
Inner function is called! b: '100'
Inner function is called! b: '100'
Inner function is called! b: '100'
我希望内部函数对同一个参数只调用一次。
据推测,每次调用 outer
时,inner
函数都会获取“re-created”,导致缓存不再起作用。这个例子证实了这一点,它从 outer
:
inner
from functools import cache
class Sample:
def outer(self, a):
@cache
def inner(b):
print(f"Inner function is called! b: '{b}'")
return b
for i in range(3):
print(f"Inner call #{i}")
print(inner(a))
return
sample = Sample()
sample.outer(100)
sample.outer(100)
sample.outer(100)
输出:
Inner call #0
Inner function is called! b: '100'
100
Inner call #1
100
Inner call #2
100
Inner call #0
Inner function is called! b: '100'
100
Inner call #1
100
Inner call #2
100
Inner call #0
Inner function is called! b: '100'
100
Inner call #1
100
Inner call #2
100
因此,缓存 确实 起作用,但仅在 inner
class 为“re-created” 之前有效。一个非常简单的解决方案是避免使用内部函数,而是依赖以下静态函数:
from functools import cache
class Sample:
@staticmethod
@cache
def _inner(b):
print(f"Inner function is called! b: '{b}'")
return b
def outer(self, a):
for i in range(3):
print(f"Inner call #{i}")
print(Sample._inner(a))
return
sample = Sample()
sample.outer(100)
sample.outer(100)
sample.outer(100)
请注意,我已将 inner
重命名为 _inner
,以表明 _inner
不打算暴露给 class 的用户。此外,我把它变成了静态方法。这允许您使用 Sample._inner(...)
而不是 self._inner(...)
。毕竟self
参数没有在_inner
中使用,所以可以是静态函数
这输出(期望的):
Inner call #0
Inner function is called! b: '100'
100
Inner call #1
100
Inner call #2
100
Inner call #0
100
Inner call #1
100
Inner call #2
100
Inner call #0
100
Inner call #1
100
Inner call #2
100
这表明已为不同的 outer
调用正确缓存所有内容。