【发布时间】:2014-07-14 04:27:36
【问题描述】:
我知道在 python 中,每件事,无论是数字、字符串、字典还是任何东西都是对象。变量名只是指向内存中的对象。现在根据this question,
>> a_dict = b_dict = c_dict = {}
这会创建一个空字典,并且所有变量都指向这个字典对象。因此,更改任何一项都会反映在其他变量中。
>> a_dict["key"] = "value" #say
>> print a_dict
>> print b_dict
>> print c_dict
会给
{'key': value}
{'key': value}
{'key': value}
我已经理解了变量指向对象的概念,所以这似乎很公平。
虽然它可能很奇怪,但既然它是一个基本的陈述,为什么会发生这种情况?
>> a = b = c = 1
>> a += 1
>> print a, b, c
2, 1, 1 # and not 2, 2, 2
问题的第一部分:为什么这里没有应用相同的概念?
实际上,当我试图为此寻找解决方案时,出现了这个疑问:
>> a_dict = {}
>> some_var = "old_value"
>> a_dict['key'] = some_var
>> some_var = "new_value"
>> print a_dict
{'key': 'old_value'} # and not {'key': 'new_value'}
这似乎违反直觉,因为我一直认为我是在告诉字典保存变量,并且更改变量指向的对象显然会反映在字典中。但这在我看来好像是在复制值,而不是引用。 这是我不明白的第二件事。
继续,我尝试了其他方法
>> class some_class(object):
.. def __init__(self):
.. self.var = "old_value"
>> some_object = some_class()
>> a_dict = {}
>> a_dict['key'] = some_object
>> some_object.var = "new_value"
>> print a_dict['key'].var
"new_value" # even though this was what i wanted and expected, it conflicts with the output in the previous code
现在,在这里,显然它被引用了。这些矛盾让我对 python 的不可预测性感到震惊,尽管我仍然喜欢它,因为我对任何其他语言都不够了解 :p 。尽管我一直认为赋值会导致对象的引用,但这两种情况是相互矛盾的。所以这是我最后的疑问。我知道它可能是那些 python gotcha's 之一。请教我。
【问题讨论】:
-
every thing, be it a number, string, dict or anything is an object这不是真的。数字和字符串(本质上)是按值传递的。 (我相信有人会用最新的 Python 术语纠正我)。 -
在我看来,一切都是对象。例如,字符串具有连接方法。 ' '.join([1,2,3]) 将给出 '1 2 3'。所以它们必须是对象。 this question 也表明了事实。
-
好的,是的,它们当然是对象。但是继续尝试将
int传递给函数并更改它。函数外的值不会改变。与字符串相同。这就是我的观点。 -
@JonathonReinhart 是的,你是对的。那不是因为在方法/函数的本地创建了一个新的 int/string。嗯..但是传递一个对象并更改其属性会反映在全局对象中。这是什么意思..??那么,为什么会出现这种差异?为什么复制 int/strings 而对象作为引用传递?
-
@JonathonReinhart 我想通了。甚至参数也作为引用传递。检查this。在更改传递给方法的参数值时,新的值对象将绑定到局部变量(覆盖传递的引用),而原始绑定(原始变量->原始值)保持不变。