具有已访问密钥内存的Python字典?
我想创建一个数据结构,其行为类似于一个字典,并添加了一个功能,即跟踪哪些键已被“使用”。请注意,我不能仅仅弹出这些值,因为它们正在被重用 结构应支持这三种情况,即在访问时将密钥标记为已使用:具有已访问密钥内存的Python字典?,python,dictionary,Python,Dictionary,我想创建一个数据结构,其行为类似于一个字典,并添加了一个功能,即跟踪哪些键已被“使用”。请注意,我不能仅仅弹出这些值,因为它们正在被重用 结构应支持这三种情况,即在访问时将密钥标记为已使用: if key in d: ... d[key] d.get(key) 这是我写的: class DictWithMemory(dict): def __init__(self, *args, **kwargs): self.memory = set() r
if key in d:
...
d[key]
d.get(key)
这是我写的:
class DictWithMemory(dict):
def __init__(self, *args, **kwargs):
self.memory = set()
return super(DictWithMemory, self).__init__(*args, **kwargs)
def __getitem__(self, key):
self.memory.add(key)
return super(DictWithMemory, self).__getitem__(key)
def __contains__(self, key):
self.memory.add(key)
return super(DictWithMemory, self).__contains__(key)
def get(self, key, d=None):
self.memory.add(key)
return super(DictWithMemory, self).get(key, d)
def unused_keys(self):
"""
Returns the list of unused keys.
"""
return set(self.keys()).difference(self.memory)
由于我对dict的内部结构不太熟悉,有没有更好的方法来实现这个结果?这里有一个解决方案,可以将元类中的所有内容抽象出来。我不确定这是否真的更优雅,但如果您改变主意如何存储使用过的密钥,它确实提供了一些封装:
class KeyRememberer(type):
def __new__(meta, classname, bases, classDict):
cls = type.__new__(meta, classname, bases, classDict)
# Define init that creates the set of remembered keys
def __init__(self, *args, **kwargs):
self.memory = set()
return super(cls, self).__init__(*args, **kwargs)
cls.__init__ = __init__
# Decorator that stores a requested key in the cache
def remember(f):
def _(self, key, *args, **kwargs):
self.memory.add(key)
return f(self, key, *args, **kwargs)
return _
# Apply the decorator to each of the default implementations
for method_name in [ '__getitem__', '__contains__', 'get' ]:
m = getattr(cls, method_name)
setattr(cls, method_name, remember(m))
return cls
class DictWithMemory(dict):
# A metaclass that ensures the object
# has a set called 'memory' as an attribute,
# which is updated on each call to __getitem__,
# __contains__, or get.
__metaclass__ = KeyRememberer
def unused_keys(self):
"""
Returns the list of unused keys.
"""
print "Used", self.memory
return list(set(super(DictWithMemory,
self).keys()).difference(self.memory))
您多久使用一次未使用的钥匙()?如果您修饰setter向集合中添加键,并使用getter尝试从此集合中删除键,那么它可能会有更好的性能-不确定优雅部分,考虑如下:为什么
unused\u keys
应该返回一个列表?它没有内在的顺序,因此它返回一个集合是有意义的。我必须说,如果我遇到一个字典,它的可观察状态被,.get()
等中的修改,我会发现这非常令人惊讶。keys()返回列表有点像是历史上的意外事件,因为集合是相对较新的添加。在Python 3中,d.keys()
返回一个迭代器,而不是一个列表。@Thomas K:unused_keys
现在返回一个集合。我喜欢使用元类来限制允许动态配置哪些方法被视为“使用者”.我同意@badzil的评论,并认为它应该更进一步,允许its客户定义或覆盖哪些方法被视为消费者——我认为这项功能可以很容易地添加。