views:

273

answers:

1

Hi, I'm subclassing dict, but ran into a problem with setitem where one assignment works, but another assignment does not. I've boiled it down to the following basic problem:

class CustomDict(dict):
 def __setitem__(self, key, value):
  super(CustomDict, self).__setitem__(key, value)

Test 1 fails:

data = {"message":"foo"}
CustomDict(data)["message"] = "bar"
print CustomDict(data) # Expected "{'message': 'bar'}". Actual is "{'message': 'foo'}".
print data # Expected "{'message': 'bar'}". Actual is "{'message': 'foo'}".

Test 2 succeeds:

data = CustomDict({"message":"foo"})
data["message"] = "bar"
print CustomDict(data) # Expected "{'message': 'bar'}". Actual matches expected.
print data # Expected "{'message': 'bar'}". Actual matches expected.

I looked online but couldn't tell whether the subclass constructor copies the dictionary so operations are performed on a different instance of the dictionary. Any advice?

+9  A: 

You are constructing new instances of CustomDict on each line. CustomDict(data) makes a new instance, which copies data.

Try this:

cd = CustomData({"message":"foo"})
cd["message"] = "bar"
print cd # prints "{'message': 'bar'}".
Ned Batchelder
Thanks, Ned. Is it a deep copy, and any suggestions on where to look in the python code to find the __init__ for dict?
Samuel Wan
It is not a deep copy. The code for dict is quite involved, 2500 lines of C. If you want to read it, it's in Objcets/dictobject.c in a Python source distribution.
Ned Batchelder
Ok, thanks very much for the information
Samuel Wan
You may want to consider marking the question as answered
246tNt