正如cpython 问题 88306中提出的,python WeakKeyDictionary对于不可散列类型失败。根据上面 python 问题中的讨论,这是一个不必要的限制,使用id键的 s 代替hash就可以了:在这种特殊情况下,ids 是 WeakKeyDictionary 中键的唯一标识符,因为当原始对象被删除。重要的是要注意,使用 ids 而不是哈希值仅在这种非常特殊的情况下才可行。
我们可以调整weakref.WeakKeyDictionary(参见要点)以实现所需的行为。总之,该实现将weakref键包装如下:
class _IdKey:
def __init__(self, key):
self._id = id(key)
def __hash__(self):
return self._id
def __eq__(self, other: typing_extensions.Self):
return self._id == other._id
def __repr__(self):
return f"<_IdKey(_id={self._id})>"
class _IdWeakRef(_IdKey):
def __init__(self, key, remove: typing.Callable[[typing.Any], None]):
super().__init__(key)
# hold weak ref to avoid garbage collection of the remove callback
self._ref = weakref.ref(key, lambda _: remove(self)) …Run Code Online (Sandbox Code Playgroud) python ×1