我有一个在迭代对象时正在构建的字典。现在可以多次访问同一个对象。而且我使用对象本身作为关键。
因此,如果同一个对象被多次访问,那么密钥就不会是唯一的,而且我的字典不再正确。
虽然我需要通过对象访问它,因为如果有人想要通过它访问内容,他们可以请求通过当前对象获取它。它是正确的,因为它将在那时访问最后一个活动对象。
所以我想知道是否有可能以某种方式包装对象,所以它会保持其状态和所有属性相同,但唯一的区别是这种新的对象实际上是唯一的。
例如:
dct = {}
for obj in some_objects_lst:
# Well this kind of wraps it, but it loses state, so if I would
# instantiate I would lose all information that was in that obj.
wrapped = type('Wrapped', (type(obj),), {})
dct[wrapped] = # add some content
现在,如果有更好的替代方案,我也想听听。
P.S。被迭代的对象将处于不同的上下文中,因此即使对象是相同的,它也会被区别对待。
更新
根据要求,提供问题来自的更好示例:
我有这个excel报告生成器模块。使用它,您可以生成各种Excel报告。为此,您需要使用python词典编写配置。
现在,在生成报告之前,它必须做两件事。获取元数据(这里的元数据是将要创建报告时每个单元格的位置),其次是解析配置以填充包含内容的单元格。
此模块中可以使用的值类型之一是公式(excel公式)。我的问题中的问题特别是可以计算公式的方法之一:为父项检索的公式值,即在其子项中。
例如想象一下这个excel文件结构:
A | B | C
Total Childs Name Amount
1 sum(childs)
2 child_1 10
3 child_2 20
4 sum(childs)
...
现在在这个例子中,单元格1A的总和,如果sum将使用表达式对其子列进行求和(在本例中为C
列),则需要为10 + 20 = 30。所有这一切都在工作,直到重复相同的对象(我称之为迭代)。因为在构建元数据时我需要存储它,以便以后检索。关键是对象本身是迭代的。所以现在当它在解析值时再次迭代时,它将不会看到所有信息,因为有些信息会被同一个对象覆盖。
例如,想象有发票对象,然后有与发票相关的合作伙伴对象,还有一些其他任意对象给出发票和合作伙伴产生特定金额。
因此,当在excel中提取此类信息时,它是这样的:
inoice1 -> partner1 -> amount_obj1, amount_obj2
invoice2 -> partner1 -> amount_obj3, amount_obj4.
请注意,示例中的合作伙伴是相同的。这是问题,因为我无法将其存储为密钥,因为在解析值时,当元数据实际保存amount_obj3
和amount_obj4
P.S不知道我是否更好地解释了它,因为有很多代码而且我不想在这里放置大量的代码。
UPDATE2
我试图从更抽象的角度解释这个问题,因为它似乎过于具体,只会让每个人更加困惑。
因此,给定对象列表和空字典,通过迭代对象来构建字典。对象充当字典中的键。它包含稍后使用的元数据。
现在可以为了不同的目的再次迭代相同的列表。完成后,它需要使用迭代对象(相同的对象,即该字典中的键)访问该字典值。但问题是,如果同一个对象被多次使用,它将只有该键的最新存储值。
这意味着对象不是唯一键。但问题是我唯一知道的是对象(当我需要检索值时)。但是因为它是相同的迭代,所以当两次访问同一个对象时,特定的迭代索引将是相同的。
因此,我认为唯一性是(index, object)
。
答案 0 :(得分:0)
我不确定我是否理解你的问题,所以这里有两个选择。如果它的对象内容很重要,请将对象副本保存为密钥。像
那样粗糙的东西new_obj = copy.deepcopy(obj)
dct[new_obj] = whatever_you_need_to_store(new_obj)
如果对象在第一次被您的代码和下一个代码检查之间没有变化,则该操作仅在第二次执行时无效。不是最佳的,但可能不是一个大问题。但是,如果确实发生了变化,您将获得新旧记录的单独记录。为了节省内存,您可能希望用散列替换副本,__str__()
方法写入对象数据或其他任何内容。但这取决于你的对象是什么;也许哈希会花费太多时间来节省大量内存。运行一些测试,看看哪些有效。
另一方面,如果为同一个对象保持相同的值很重要,那么它内部的数据是否已经改变(比如,对象是一个可以在登录之间更改其数据的用户会话)和注销),使用对象ID。不是内置id()
函数,因为如果对象被GCed或删除,其他一些对象可能会得到它的id。为对象定义id
属性,并确保不同的对象不可能获得相同的对象。