4 python
我需要一组对象,这些对象可以通过每个对象共有的某个(唯一)属性进行查找.现在我正在使用一个dicitionary将字典键分配给属性.这是我现在拥有的一个例子:
class Item():
def __init__(self, uniq_key, title=None):
self.key = uniq_key
self.title = title
item_instance_1 = Item("unique_key1", title="foo")
item_instance_2 = Item("unique_key3", title="foo")
item_instance_3 = Item("unique_key2", title="foo")
item_collection = {
item_instance_1.key: item_instance_1,
item_instance_2.key: item_instance_2,
item_instance_3.key: item_instance_3
}
item_instance_1.key = "new_key"
Run Code Online (Sandbox Code Playgroud)
现在这似乎是一个相当麻烦的解决方案,因为密钥不是对属性的引用,而是在赋值时获取key-attribute的值,这意味着:
使用列表并迭代对象似乎效率更低.
那么,对于这种特殊情况,是否有比dict更合适的数据结构,一组对象给我随机访问基于某个对象属性?
这需要与Python 2.4一起使用,因为这就是我所困扰的(在工作中).
如果不是很明显,我是Python的新手.
实际上,您不必担心重复信息:dict的键和对象的.key属性只是对完全相同对象的两个引用.
唯一真正的问题是"如果.key重新分配会怎么样".那么,显然你必须使用一个属性来更新所有相关的dicts以及实例的属性; 所以每个对象必须知道它可以被注册的所有序列.理想情况下,人们可能希望为此目的使用弱引用,以避免循环依赖,但是,唉,您不能将weakref.ref(或代理)带到dict.所以,我在这里使用普通引用(替代方法不是使用dict实例,而是使用一些特殊的子类 - 不方便).
def enregister(d, obj):
obj.ds.append(d)
d[obj.key] = obj
class Item(object):
def __init__(self, uniq_key, title=None):
self._key = uniq_key
self.title = title
self.ds = []
def adjust_key(self, newkey):
newds = [d for d in self.ds if self._key in d]
for d in newds:
del d[self._key]
d[newkey] = self
self.ds = newds
self._key = newkey
def get_key(self):
return self._key
key = property(get_key, adjust_key)
Run Code Online (Sandbox Code Playgroud)
编辑:如果你想要一个包含Item的所有实例的单个集合,那就更容易了,因为你可以使集合成为一个类级属性; 事实上它可以是一个WeakValueDictionary,以避免错误地保持项目存活,如果这是你需要的.即:
class Item(object):
all = weakref.WeakValueDictionary()
def __init__(self, uniq_key, title=None):
self._key = uniq_key
self.title = title
# here, if needed, you could check that the key
# is not ALREADY present in self.all
self.all[self._key] = self
def adjust_key(self, newkey):
# "key non-uniqueness" could be checked here too
del self.all[self._key]
self.all[newkey] = self
self._key = newkey
def get_key(self):
return self._key
key = property(get_key, adjust_key)
Run Code Online (Sandbox Code Playgroud)
现在你可以使用Item.all['akey'],Item.all.get('akey'),for akey in Item.all:,等等-类型的字典所有丰富功能.