weakref (WeakKeyDictionary) to frame (FrameType) objects



我想有一个从活动帧(FrameType)对象到一些数据的字典映射。活动的意思是它在当前执行堆栈跟踪中。

但是,保留对frame对象的引用并不是一个好主意,因为这也会使帧保持非活动状态,并且很快就会耗尽内存,因为所有的引用都指向所有的局部变量。

自然的解决方案是使用对框架对象的弱引用,或者更具体地说是WeakKeyDictionary

但是,目前还不能创建一个指向框架对象的弱引用:

import weakref
import sys
f = sys._getframe()
weakref.ref(f)

收益率

TypeError: cannot create weak reference to 'frame' object

我认为这是一个CPython实现细节?

那么,有哪些选择呢?

我可能无论如何都可以创建引用,但当它们不再活跃时,请尽快清理它们。我如何检查一个框架对象是否处于活动状态?

这是一个疯狂的想法:如果你不能保持对框架的引用,让框架保持对你的引用。

class FrameDict:
def __init__(self):
self._data_by_frame_id = {}

def __setitem__(self, frame, data):
frame_id = id(frame)

# Make the frame hold a reference to a KeyDeleter, so when the frame
# dies, the KeyDeleter dies, and the frame is removed from the dict
deleter = KeyDeleter(self._data_by_frame_id, frame_id)
frame.f_locals[deleter] = deleter
self._data_by_frame_id[frame_id] = data

def __getitem__(self, frame):
frame_id = id(frame)
return self._data_by_frame_id[frame_id]

class KeyDeleter:
def __init__(self, mapping, key):
self.mapping = mapping
self.key = key

def __del__(self):
del self.mapping[self.key]

演示:

import inspect
def new_frame():
return inspect.currentframe()
frame_dict = FrameDict()
frame = new_frame()
frame_dict[frame] = 'foobar'
print(frame_dict[frame])  # foobar
del frame
print(frame_dict._data_by_frame_id)  # {}

相关内容

  • 没有找到相关文章

最新更新