Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
深度复制用户定义的python字典_Python_Dictionary_Deep Copy - Fatal编程技术网

深度复制用户定义的python字典

深度复制用户定义的python字典,python,dictionary,deep-copy,Python,Dictionary,Deep Copy,我有一个用户定义的字典(对python的内置dict对象进行子分类),它不允许直接修改dict: class customDict(dict): """ This dict does not allow the direct modification of its entries(e.g., d['a'] = 5 or del d['a']) """ def __init__(self, *args, **kwargs): self.upd

我有一个用户定义的字典(对python的内置dict对象进行子分类),它不允许直接修改dict:

class customDict(dict):
    """
    This dict does not allow the direct modification of
    its entries(e.g., d['a'] = 5 or del d['a'])
    """
    def __init__(self, *args, **kwargs):
        self.update(*args, **kwargs)

    def __setitem__(self,key,value):
        raise Exception('You cannot directly modify this dictionary. Use set_[property_name] method instead')

    def __delitem__(self,key):
        raise Exception('You cannot directly modify this dictionary. Use set_[property_name] method instead')
我的问题是我无法使用copy.deepcopy深度复制这本词典。下面是一个例子:

d1 = customDict({'a':1,'b':2,'c':3})
print d1
d2 = deepcopy(d1)
print d2
它抛出我为setitem定义的异常:

Exception: You cannot directly modify this dictionary. Use set_[property_name] method instead
我尝试按如下所示覆盖deepcopy方法:

这不会抛出任何错误,但会返回一个空字典:

d1 = customDict({'a':1,'b':2,'c':3})
print d1
d2 = deepcopy(d1)
print d2

{'a': 1, 'c': 3, 'b': 2} 
{}

有什么办法可以解决这个问题吗?

类似的方法应该可以在不必更改deepcopy的情况下工作

x2 = customList(copy.deepcopy(list(x1)))

这将把
x1
转换为
列表
deepcopy,然后在分配给
x2
之前将其转换为
customList
,类似的操作应该可以在不必更改deepcopy的情况下工作

x2 = customList(copy.deepcopy(list(x1)))

这将把
x1
转换为
列表
deepcopy,然后将其设置为
customList
,然后分配给
x2
您的
deepcopy
实现不起作用,因为
dict
的值未存储在
dict
是一个特殊的类。您可以使用dict的deepcopy调用
\uuuu init\uuuu

def __deepcopy__(self, memo):
    def _deepcopy_dict(x, memo):
        y = {}
        memo[id(x)] = y
        for key, value in x.iteritems():
            y[deepcopy(key, memo)] = deepcopy(value, memo)
        return y
    cls = self.__class__
    result = cls.__new__(cls)
    result.__init__(_deepcopy_dict(self, memo))
    memo[id(self)] = result
    for k, v in self.__dict__.items():
        setattr(result, k, deepcopy(v, memo))
    return result
这个节目

d1 = customDict({'a': 2,'b': [3, 4]})
d2 = deepcopy(d1)
d2['b'].append(5)

print d1
print d2
输出

{'a': 2, 'b': [3, 4]}
{'a': 2, 'b': [3, 4, 5]}

您的
deepcopy
实现不起作用,因为
dict
的值未存储在
\uuuuuu dict\uuu
dict
是一个特殊的类。您可以使用dict的deepcopy调用
\uuuu init\uuuu

def __deepcopy__(self, memo):
    def _deepcopy_dict(x, memo):
        y = {}
        memo[id(x)] = y
        for key, value in x.iteritems():
            y[deepcopy(key, memo)] = deepcopy(value, memo)
        return y
    cls = self.__class__
    result = cls.__new__(cls)
    result.__init__(_deepcopy_dict(self, memo))
    memo[id(self)] = result
    for k, v in self.__dict__.items():
        setattr(result, k, deepcopy(v, memo))
    return result
这个节目

d1 = customDict({'a': 2,'b': [3, 4]})
d2 = deepcopy(d1)
d2['b'].append(5)

print d1
print d2
输出

{'a': 2, 'b': [3, 4]}
{'a': 2, 'b': [3, 4, 5]}


继承可能不是解决这个问题的好办法。如果你的列表没有做元组还没有做的事情,就使用元组吧。否则,请使用代理设计模式(“has a“not”是a”)为什么需要深度复制不可变列表?这也是一个好问题!:)你问的是一个合法的问题!实际上,我首先创建了一个用户定义的dict,它不允许直接修改它的条目,然后对一个列表做了同样的操作,忘记了我可以使用元组来代替它!我已经编辑了这个问题,并将用户定义的列表更改为用户定义的dict。一个相关的问题是,当我将deepcopy重新定义为“return customDict(deepcopy(dict(self))”时,如何更改此用户定义的deepcopy方法的递归限制。我使用的是sys.setrecursionlimit(10000),但仍然出现以下错误:“RuntimeError:超出了最大递归深度”。但是,当使用malbarbo建议的其他方法时,我没有发现这个错误。继承可能不是解决这个问题的好方法。如果你的列表没有做元组还没有做的事情,就使用元组吧。否则,请使用代理设计模式(“has a“not”是a”)为什么需要深度复制不可变列表?这也是一个好问题!:)你问的是一个合法的问题!实际上,我首先创建了一个用户定义的dict,它不允许直接修改它的条目,然后对一个列表做了同样的操作,忘记了我可以使用元组来代替它!我已经编辑了这个问题,并将用户定义的列表更改为用户定义的dict。一个相关的问题是,当我将deepcopy重新定义为“return customDict(deepcopy(dict(self))”时,如何更改此用户定义的deepcopy方法的递归限制。我使用的是sys.setrecursionlimit(10000),但仍然出现以下错误:“RuntimeError:超出了最大递归深度”。但是,当使用malbarbo建议的另一种方法时,我没有发现这个错误。看起来
memo
存储的是原件的参考,而不是副本。实际上,它应该是
memo[id(self)]=self
?问题中链接的第一个答案也表明了这一点。不。例如,这似乎不适用于字典。这里有一个例子:d1=customDict({'a':2,'b':[3,4]})d2=deepcopy(d1)d2['b'])。append(5)print d1 print d2{'a':2,'b':[3,4,5]}{'a':2,'b':[3,4,5]}print d2它看起来像是
memo
存储了原件的引用,而不是副本。实际上,它应该是
memo[id(self)]=self
?问题中链接的第一个答案也表明了这一点。不。例如,这似乎不适用于字典。这里有一个例子:d1=customDict({'a':2,'b':[3,4]})d2=deepcopy(d1)d2['b'])!唯一的一点是,我实际上是在复制一个类,在这个类中,这个列表充当一个实例变量。所以,我仍然需要覆盖deeopcoopy方法。尽管如此,我还是在deepcopy的定义中加入了:returncustomlist(deepcopy(list(self)),它工作得非常好!我没有使用customList(deepcopy(list(self)),而是使用self。它工作得很好,但我遇到的问题是,即使我使用sys.setrecursionlimit(10000),我也会得到“RuntimeError:maximum recursion depth Oversed”(运行时错误:超过最大递归深度)为什么要调用
\uu init\uuuu()
?我想当你调用
self.\uuuuu init\uuuuu(deepcopy(list(self))
时,你导致了一个无限递归。对不起,我应该告诉你我将问题从customList更改为customDict。正如我在第一篇评论中提到的,我使用的这个customDict对象作为类的实例属性。因此,我仍然需要覆盖customDict中的deepcopy方法,以便能够对该类进行deepcopy。deepcopy(dict(self))将customDict对象转换为字典,然后再进行deepcopy,但我必须将其转换回customDict,我想我可以自己完成。deepcopy(dict(self))您应该可以调用
customDict(deepcopy(dict(self))
这是一个很好的建议!唯一的一点是,我实际上是在复制一个类,在这个类中,这个列表充当一个实例变量。所以,我仍然需要覆盖deeopcoopy方法。尽管如此,我还是在deepcopy的定义中加入了:returncustomlist(deepcopy(list(self)),它工作得非常好!而不是我们