使用python dict查找可变对象

使用python dict查找可变对象,python,dictionary,Python,Dictionary,我有一堆文件对象和一堆文件夹对象。每个文件夹都有一个文件列表。现在,有时我想查找某个文件所在的文件夹。我不想遍历所有的文件夹和文件,所以我创建了一个查找dictfile->folder folder = Folder() myfile = File() folder_lookup = {} # This is pseudocode, I don't actually reach into the Folder # object, but have an appropriate method f

我有一堆
文件
对象和一堆
文件夹
对象。每个文件夹都有一个
文件列表。现在,有时我想查找某个文件所在的文件夹。我不想遍历所有的文件夹和文件,所以我创建了一个查找
dict
file->folder

folder = Folder()
myfile = File()
folder_lookup = {}

# This is pseudocode, I don't actually reach into the Folder
# object, but have an appropriate method
folder.files.append(myfile)
folder_lookup[myfile] = folder
现在,问题是,文件是可变对象。我的应用程序是围绕这个事实构建的。我更改了它们的属性,GUI会得到相应的通知和更新。当然,你不能把可变对象放在dicts中。因此,我首先尝试的是基于当前内容生成哈希,基本上:

def __hash__(self):
    return hash((self.title, ...))
这当然不起作用,因为当对象的内容发生变化时,它的散列(以及它的标识)发生了变化,一切都变得一团糟。我需要的是一个保持其身份的对象,尽管其内容会发生变化。我尝试了各种方法,比如让
\uuuuu散列
返回
id(self)
,重写
\uuuuuuu eq\uuuu
等等,但从未找到令人满意的解决方案。一个复杂的问题是整个结构应该是可酸洗的,因此这意味着我必须在创建时存储
id
,因为我想在酸洗时它可能会改变


因此,我基本上希望使用对象的标识(而不是其状态)快速查找与对象相关的数据。事实上,我已经为我的问题找到了一个非常好的pythonic解决方法,我可能会很快发布,但我想看看是否有其他人提出了解决方案

写这封信我觉得很肮脏。只需将文件夹作为文件的一个属性

class dodgy(list):
    def __init__(self, title):
        self.title = title
        super(list, self).__init__()
        self.store = type("store", (object,), {"blanket" : self})
    def __hash__(self):
        return hash(self.store)

innocent_d = {}
dodge_1 = dodgy("dodge_1")
dodge_2 = dodgy("dodge_2")
innocent_d[dodge_1] = dodge_1.title
innocent_d[dodge_2] = dodge_2.title

print innocent_d[dodge_1]
dodge_1.extend(range(5))
dodge_1.title = "oh no"
print innocent_d[dodge_1]

好的,每个人都注意到了一个非常明显的解决方法(我花了几天的时间才想出),只需在
文件
上添加一个属性,告诉您它在哪个文件夹中。(别担心,我也是这么做的。)

但是,事实证明我是在错误的假设下工作的。你不应该使用可变对象作为键,但这并不意味着你不能(恶魔般的笑声)!
\uuuuuuuuuuuuuuuuuuuuu散列
的默认实现返回一个唯一的值,该值可能来自对象的地址,在时间上保持不变。默认的
\uuuu eq\uuuu
遵循相同的对象标识概念

所以,您可以将可变对象放在dict中,它们按照预期工作(如果您期望基于实例而不是基于值的相等)

另见:

我遇到了一些问题,因为我正在酸洗/取消酸洗对象,这当然改变了哈希。可以在构造函数中生成一个唯一的ID,并使用该ID实现相等,并派生一个哈希来克服这个问题


(奇怪的是,为什么需要这样一个“基于实例标识的查找”dict:我一直在试验一种。你有纯python对象,把它们放在列表/容器中,可以在属性上定义索引,以便更快地查找、复杂的查询等等。对于外键(1:n关系)我可以只使用容器,但对于反向链接,如果我不想修改n侧的对象,我必须想出一些巧妙的方法。)

文件对象的属性告诉您它们不在哪个文件夹中?同意Jblasco。每次创建新文件时,请尝试使用唯一属性object@Jblasco:是的,这就是我曾经使用过的非常简单的pythonic解决方法:-)。但是,我仍然想知道是否有一种方法可以使用外部dict实现。原因之一:可能有不同类别的文件夹(目录、标记、智能搜索)。我必须为每种类型添加一个特殊的属性。然后唯一的属性可以是一个元组,如:(“Folder”,“FolderType”)。您可以覆盖
文件
s
\uu str\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。尤其是您放入
存储中的内容
。但是,我从不需要File/dodge对象成为list子类。如果它是一个普通的对象子类,显然如果小心的话,可以将其用作键。是的,我选择了一个列表对象只是为了用一个不可损坏的类型来演示它。