Pythonで辞書やリストをcopyメソッドでコピーすると、javaのclone()と同じように浅いコピーとなるようだ。
test1.py
mydict = {'val': 'aa', 'dict': {'val': 'bb'}}
copy_dict = mydict.copy()
print(mydict)
# -> {'val': 'aa', 'dict': {'val': 'bb'}}
print(copy_dict)
# -> {'val': 'aa', 'dict': {'val': 'bb'}}
copy_dict['val'] = 'aa modified'
copy_dict['dict']['val'] = 'bb modified'
print(mydict)
# -> {'val': 'aa', 'dict': {'val': 'bb modified'}}
print(copy_dict)
# -> {'val': 'aa modified', 'dict': {'val': 'bb modified'}}
copy_dictで{'val': 'aa'}部分を書き換えても、mydict側は書き換わらないが、{'dict': {'val': 'bb'}}部分を書き換えると、mydict側も書き換わってしまう。
つまり、copyメソッドでは再帰的にオブジェクト自体のコピーをしてくれないらしい。
これは、deepcopyを使うことで解決できる。
test2.py
from copy import deepcopy
mydict = {'val': 'aa', 'dict': {'val': 'bb'}}
copy_dict = deepcopy(mydict)
print(mydict)
# -> {'val': 'aa', 'dict': {'val': 'bb'}}
print(copy_dict)
# -> {'val': 'aa', 'dict': {'val': 'bb'}}
copy_dict['val'] = 'aa modified'
copy_dict['dict']['val'] = 'bb modified'
print(mydict)
# -> {'val': 'aa', 'dict': {'val': 'bb'}}
print(copy_dict)
# -> {'val': 'aa modified', 'dict': {'val': 'bb modified'}}