python类dict引用-避免重复数据

python类dict引用-避免重复数据,python,class,object,dictionary,memory,Python,Class,Object,Dictionary,Memory,我有一个关于Python如何处理类之间的引用和它们之间传递的对象的问题。在我的程序的一个特定部分中,我遇到了一个引用问题,我不确定Python是否实际引用了同一个dict对象,或者它是否在内存中为新对象的每个实例化创建了大量重复项,这将是一个问题。我也不知道如何测试它,因为我引用的对象只是一个字典,我不能像打印类对象那样打印它来查看ID 下面是我正在做的一个超级简化的例子: class Container(object): def __init__(self, target, items

我有一个关于Python如何处理类之间的引用和它们之间传递的对象的问题。在我的程序的一个特定部分中,我遇到了一个引用问题,我不确定Python是否实际引用了同一个dict对象,或者它是否在内存中为新对象的每个实例化创建了大量重复项,这将是一个问题。我也不知道如何测试它,因为我引用的对象只是一个字典,我不能像打印类对象那样打印它来查看ID

下面是我正在做的一个超级简化的例子:

class Container(object):
    def __init__(self, target, items_dict):
        self.target = target
        self.sub_items = []
        self.load_items(items_dict)

    def load_items(self, items_dict):
        target = self.target
        for item in items_dict:
            self.sub_items.append(SubItem(items_dict[item], target))

class SubItem(object):
    def __init__(self, data, target):
        self.attr1 = data['attr1']
        self.attr2 = data['attr2']
        self.target = target

    def mult(self):
        return self.attr1 * self.target['a']

target_to_load = {'a': 1}
items_to_load = {
    'objone': {'attr1': 1, 'attr2': 2},
    'objtwo': {'attr1': 1, 'attr2': 2}
}

new_container = Container(target_to_load, items_to_load)
print new_container.sub_items[0].mult()
这段代码将dict传递给子项的方式,是Python创建字典数据的实际副本,还是每个子项都要引用内存中的同一个字典?在程序执行期间,我可能只有三个或四个唯一的目标,但我可能有数千个子项,因此这可能会导致内存效率极低

问题是,我不知道Python是否以及如何弄清楚它在幕后会做什么,但如果它正在复制数据,也许更有效的解决方案是将self传递给SubItem,以便SubItem可以指向Container.target的引用:

class Container(object):
    def __init__(self, target, items_dict):
        self.target = target
        self.sub_items = []
        self.load_items(items_dict)

    def load_items(self, items_dict):
        target = self.target
        for item in items_dict:
            self.sub_items.append(SubItem(items_dict[item], self))


class SubItem(object):
    def __init__(self, data, container):
        self.attr1 = data['attr1']
        self.attr2 = data['attr2']
        self.target = container.target

    def mult(self):
        return self.attr1 * self.target['a']


target_to_load = {'a': 1}
items_to_load = {
    'objone': {'attr1': 1, 'attr2': 2},
    'objtwo': {'attr1': 1, 'attr2': 2}
}


new_container = Container(target_to_load, items_to_load)
print new_container.sub_items[0].mult()

但是,我不知道这是否更有效或更必要,因此,如果您能在这种情况下了解Python后端的更多细节,我将不胜感激。

“我也不知道如何测试这一点,因为我引用的对象只是一个字典,我无法将其像类对象一样打印以查看ID。”这与“类对象”与内置对象类型无关。类对象继承它们的
repr
表单
object
,这就是为什么它们看起来都一样,但这是可重写的行为。在任何情况下,如果您确实不想查看对象是否相同,则始终可以使用
id(my_object)
。或者使用
is
操作符。在任何情况下,在Python中,将对象作为参数传递或指定给名称或属性都不会复制数据。在引擎盖下,它都是
Py_对象
指针(当然是在CPython中)。因此,如果您的问题是
target
作为参数传递时是否被复制,那么答案是否定的。啊,我不知道id()。所以本质上,我已经用Container.target=target为字典分配了一个名称空间,然后当将这个dict传递给SubItem类时,它仍然是同一个字典,只是被分配给了另一个名称SubItem.target?在这种情况下,如果我要修改SubItem.target,那么Container.target将反映相同的更改?您应该看看Ned Batchelder在上的(StackOverflow图例)文章。是的,没错。请参阅上面的链接。在python中,赋值就像在对象上放置一个名称标记<代码>x=对象();y=x不会复制
x
,而是将同一对象指定给两个不同的名称。