TY *_*Lim 1 python dictionary python-3.x
我有一个类,其属性基于用户定义的字典初始化(使用 JSON 读取):
class Knight(object):
def __init__(self, traits):
for k, v in traits.items():
self.__setattr__(k, v)
traitfile = json.load(open(input(), 'r'))
# Where the input file is e.g.
# {'helmet': 'horned',
# 'sword': 'big',
# 'words': ['Ni!', 'Peng', 'Neee-Wom!']}
Run Code Online (Sandbox Code Playgroud)
当我实例化对象时,helmet
、sword
、 和words
成为预期的属性。但是,如果我随后更改实例属性,它似乎会影响最初初始化对象的原始字典:
tall_knight = Knight(traitfile)
print(tall_knight.words) # prints ['Ni!', 'Peng', 'Neee-Wom!']
print(traitfile['words']) # also prints ['Ni!', 'Peng', 'Neee-Wom!']
tall_knight.words.append('Ekke ekke!')
print(tall_knight.words) # prints ['Ni!', 'Peng', 'Neee-Wom!', 'Ekke ekke!'] as expected
print(traitfile['words']) # also prints ['Ni!', 'Peng', 'Neee-Wom!', 'Ekke ekke!'] NOT EXPECTED
Run Code Online (Sandbox Code Playgroud)
我没想到对象属性的更改会影响它初始化的字典。我认为实例化的全部意义在于,实例是它自己的实例!这里发生了什么?!(我怎样才能阻止它?)
您的问题是,这traitfile['words']
是一个列表,当您将其复制到 时tall_knight.words
,您正在复制对列表的引用,而不是其中的值。因此,当您修改 中的列表时tall_knight
,您也会修改 中的值traitfile['words']
。copy.copy
您可以通过使用(或者copy.deepcopy
如果值可以嵌套)复制对象中的值来解决此问题:
import copy()
class Knight(object):
def __init__(self, traits):
for k, v in traits.items():
self.__setattr__(k, copy.copy(v))
Run Code Online (Sandbox Code Playgroud)