UserDict has __copy__ and .copy() methods.The former is triggered by copy.copy(x) and the latter is by x.copy(). in copy(), it first set self.data to {} and in the end uses c.update(self) to fill out c.data. BUT, update() will trigger __setitem__ , possibly making c.data differs from self.data
from collections import UserDict
class Foo(UserDict):
def __setitem__(self, key, value):
if isinstance(key, int):
self.data[key] = value
a = Foo({1:2})
# we force it to set key of str type
a.data['3'] = 4
# two different ways to copy
from copy import copy
b = copy(a)
c = a.copy()
# this copy(a) works fine, but a.copy() is not what we expected!!!
assert b == a
assert not c == a
why this inconsistence exists? why not just this:
def copy(self):
if self.__class__ is UserDict:
return UserDict(self.data.copy())
import copy
return copy.copy(self)
I didn't know you can subclass dict
directly in Python3.
See : How to "perfectly" override a dict?
Advantages of UserDict class in Python .
Anyway MAYBE there is no reason to bother with UserDict
anymore.
See the website Trey Hunner
mentioned : https://treyhunner.com/2019/04/why-you-shouldnt-inherit-from-list-and-dict-in-python/