numpy.array 对象本身是可哈希的,只要它们是不可变的。然而,由于 numpy 数组通常是可变的(即它们的内容可以被修改),所以使用 numpy.array 作为 lru_cache 的返回值可能会导致问题。如果数组被修改了,它的哈希值也会改变,这将导致缓存失效。

如果你想要使用 lru_cache 并且希望返回一个 numpy.array,你应该确保:

  1. 数组是不可变的:这意味着在函数返回数组之后,你不会修改它。如果你需要返回一个可变的数组,考虑返回一个数组的副本,或者使用 numpy.copy() 方法来确保返回的是原始数据的独立副本。
  2. 使用 .cache 替代 .lru_cache:在 Python 3.9 及以上版本中,functools 模块提供了 cache 函数,它是 lru_cache 的无参数版本,它不需要返回值是可哈希的,因为它使用函数的参数作为缓存键。

下面是一个使用 lru_cachenumpy.array 的示例:

from functools import lru_cache
import numpy as np

@lru_cache(maxsize=128)
def get_array():
    # 创建一个 numpy 数组并返回
    # 确保这个数组不会被修改
    return np.array([1, 2, 3])

# 第一次调用,将缓存数组
arr1 = get_array()

# 第二次调用,将使用缓存的数组
arr2 = get_array()

# 检查两个数组是否是同一个对象
print(np.may_share_memory(arr1, arr2))  # 可能输出 True 或 False
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

请注意,numpy.may_share_memory(a, b) 函数检查两个数组是否共享内存块。如果输出是 True,这意味着 lru_cache 可能返回了相同的数组对象,但这也意味着如果你修改了 arr1arr2,另一个也会受到影响。

如果你需要确保返回的数组是不可变的副本,你可以使用 np.array([...]).copy() 来创建一个新的数组副本:

@lru_cache(maxsize=128)
def get_array():
    # 创建一个 numpy 数组的副本并返回
    return np.array([1, 2, 3]).copy()
  • 1.
  • 2.
  • 3.
  • 4.

这样,即使 numpy.array 是可变的,返回的是数组的一个副本,这个副本是不可变的,可以安全地用作 lru_cache 的返回值。