Python - 在 class 函数中更新 class 自身字典
Python - update a class self dictionary inside a class function
我在 class (self.d1) 中声明了一个字典。
调用 f1 函数后,self.d1 需要更新为 f1
内声明的本地字典
import copy
class num:
def __init__(self):
self.d1 = {'a':1, 'b':2, 'c':3}
self.f1(self.d1)
print self.d1
def f1(self,d):
d2 = {'d':4, 'e':5, 'f':6}
d = copy.deepcopy(d2)
test = num()
我希望输出为:
{'d':4, 'e':5, 'f':6}
但输出是
{'a':1, 'b':2, 'c':3}
我想了解问题所在,而不仅仅是解决方案
你的问题是
d = deepcopy(...)
您并没有改变 d
引用的词典,您只是将 d
更改为引用另一个词典(在本例中为新创建的词典副本)。
您不想分配给 f1()
中的 d
,因为它失去了必须对 self.d1
的旧绑定。所以赋值后 d
只是 f1()
.
的局部变量
但是你可以用这个实现你想要的:
class num:
def __init__(self):
self.d1 = {'a':1, 'b':2, 'c':3}
self.f1(self.d1)
print self.d1
def f1(self,d):
d2 = {'d':4, 'e':5, 'f':6}
d.clear()
d.update(d2)
test = num()
输出
{'e': 5, 'd': 4, 'f': 6}
请注意,我的代码没有对 f1()
中的 d
进行赋值,它只调用 改变 现有对象。
有关此主题和相关主题的更多参考,请参阅 SO stalwart Ned Batchelder 撰写的这篇优秀文章:Facts and myths about Python names and values
如果您将值 {'a' : 1}
分配给某个变量 self.d1
,那么该变量将保留对该值的引用。这意味着您可以通过访问它来更改 d1
的值,例如:self.d1['a'] = 2
,现在该值将是 {'a' : 2'}
。
您还可以更改变量 self.d1
的引用,方法是将其分配给新变量。因此,在您的函数 f1
中,您实际上更改了 d
指向的引用,而不是它引用的值。并且由于函数的作用域,self.d1
仍将在函数作用域之外保留对原始值的引用。
另一种解释...
class num:
def __init__(self):
self.d1 = {'a':1, 'b':2, 'c':3}
# calling a function with a dictionary copies the *reference* to the
# dictionary object.
print 'first test ..'
self.test_dict_arg_1(self.d1)
print self.d1
print 'second test ...'
self.test_dict_arg_2(self.d1)
print self.d1
def test_dict_arg_1(self, d):
d2 = {'d':4, 'e':5, 'f':6}
# now you load d with a new value, the referenced object is untouched
d = d2
def test_dict_arg_2(self, d):
d2 = {'d':4, 'e':5, 'f':6}
# now you work with the referenced object
d.clear()
d.update(d2)
我在 class (self.d1) 中声明了一个字典。 调用 f1 函数后,self.d1 需要更新为 f1
内声明的本地字典import copy
class num:
def __init__(self):
self.d1 = {'a':1, 'b':2, 'c':3}
self.f1(self.d1)
print self.d1
def f1(self,d):
d2 = {'d':4, 'e':5, 'f':6}
d = copy.deepcopy(d2)
test = num()
我希望输出为:
{'d':4, 'e':5, 'f':6}
但输出是
{'a':1, 'b':2, 'c':3}
我想了解问题所在,而不仅仅是解决方案
你的问题是
d = deepcopy(...)
您并没有改变 d
引用的词典,您只是将 d
更改为引用另一个词典(在本例中为新创建的词典副本)。
您不想分配给 f1()
中的 d
,因为它失去了必须对 self.d1
的旧绑定。所以赋值后 d
只是 f1()
.
但是你可以用这个实现你想要的:
class num:
def __init__(self):
self.d1 = {'a':1, 'b':2, 'c':3}
self.f1(self.d1)
print self.d1
def f1(self,d):
d2 = {'d':4, 'e':5, 'f':6}
d.clear()
d.update(d2)
test = num()
输出
{'e': 5, 'd': 4, 'f': 6}
请注意,我的代码没有对 f1()
中的 d
进行赋值,它只调用 改变 现有对象。
有关此主题和相关主题的更多参考,请参阅 SO stalwart Ned Batchelder 撰写的这篇优秀文章:Facts and myths about Python names and values
如果您将值 {'a' : 1}
分配给某个变量 self.d1
,那么该变量将保留对该值的引用。这意味着您可以通过访问它来更改 d1
的值,例如:self.d1['a'] = 2
,现在该值将是 {'a' : 2'}
。
您还可以更改变量 self.d1
的引用,方法是将其分配给新变量。因此,在您的函数 f1
中,您实际上更改了 d
指向的引用,而不是它引用的值。并且由于函数的作用域,self.d1
仍将在函数作用域之外保留对原始值的引用。
另一种解释...
class num:
def __init__(self):
self.d1 = {'a':1, 'b':2, 'c':3}
# calling a function with a dictionary copies the *reference* to the
# dictionary object.
print 'first test ..'
self.test_dict_arg_1(self.d1)
print self.d1
print 'second test ...'
self.test_dict_arg_2(self.d1)
print self.d1
def test_dict_arg_1(self, d):
d2 = {'d':4, 'e':5, 'f':6}
# now you load d with a new value, the referenced object is untouched
d = d2
def test_dict_arg_2(self, d):
d2 = {'d':4, 'e':5, 'f':6}
# now you work with the referenced object
d.clear()
d.update(d2)