当前位置: 动力学知识库 > 问答 > 编程问答 >

Deep copying a user-defined python dictionary

问题描述:

I have a user defined dictionary (sub-classing python's built-in dict object), which does not allow modifying the dict directly:

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')

My problem is that I am not able to deep copy this dictionary using copy.deepcopy. Here's an example:

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

print d1

d2 = deepcopy(d1)

print d2

where it throws the exception I've defined myself for setitem:

Exception: You cannot directly modify this dictionary. Use set_[property_name] method instead

I tried overwriting deepcopy method as follows as suggested here:

def __deepcopy__(self, memo):

cls = self.__class__

result = cls.__new__(cls)

memo[id(self)] = result

for k, v in self.__dict__.items():

setattr(result, k, deepcopy(v, memo))

return result

This doesn't throw any errors but it returns an empty dictionary:

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

print d1

d2 = deepcopy(d1)

print d2

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

{}

Any ideas how to fix this?

网友答案:

Your deepcopy implementation does not work because the values of dict is not stored in __dict__. dict is a special class. You can make it work calling __init__ with a deepcopy of the dict.

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

This program

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

print d1
print d2

Outputs

{'a': 2, 'b': [3, 4]}
{'a': 2, 'b': [3, 4, 5]}
网友答案:

Something like this should work without having to change deepcopy.

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

This will cast x1 to a list deepcopy it then make it a customList before assigning to x2.

分享给朋友:
您可能感兴趣的文章:
随机阅读: