Python将什么视为引用类型?

时间:2011-05-28 00:36:44

标签: python sequences value-type reference-type

我假设Python中的序列类型是值类型。事实证明它们是引用类型(意味着当分配给新变量但引用时,不会复制变量的值)。所以现在我想知道,Python中的值类型是什么?也就是说,我可以将Python中的哪些类型分配给新变量而不必担心变量被引用?

3 个答案:

答案 0 :(得分:20)

Python中的所有值都是引用。您需要担心的是,如果类型可变。基本数字和字符串类型以及tuplefrozenset是不可变的;绑定到其中一种类型的对象的名称只能被反弹,而不能发生变异。

>>> t = 1, 2, 3
>>> t[1] = 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

答案 1 :(得分:4)

上面的答案是正确的,但我反对“参考”的语义。

类C语言将变量视为固定存储区,其中放置了值。调用函数时,会创建一组新的存储桶,并将值复制到这些存储桶中。有时,存储桶是按引用传递的,实际上会成为调用者存储桶的别名。

另一方面,Python将变量视为值(对象)的标签(名称)。调用函数时,会创建一组新标签并将其打到这些相同的对象上。

在Python的上下文中提及“引用”是没有意义的,因为在所有其他语言中,“引用”意味着“值”的替代。 Python没有这种二元性;它只是传递并分配对象。没有任何内容被引用到

也许是Nitpicky,但这个术语对于C ++程序员来说并没有让人感到困惑,例如通过引用听到Python传递,并且不了解如何重新分配调用者的名字。

答案 2 :(得分:1)

来自使用强类型Swift语言的iOS开发,Python参考有点令人困惑,因此我决定做一些比较。这是摘要:-

  • 在为python分配变量时,说a = 10只是指向/引用对象10,该对象存储在内存中。因此,如果该对象发生更改,那么变量a的值也会发生变化,但是更改a不会更改对象10,这与诸如{{1} }。

在此要说明的是一个示例:-

Int

让我们检查一下更复杂的数据结构 # "a" points to an object in this case 10 a = 10 # "b" points to the same object which a points but does not point to a variable a. b = a # Now if we change "a" to point to another object in memory say 20. a = 20 # "b" still points to the old object 10 in other words # "b == 10" but "a == 20", This is because "b" was never pointing to the variable "a" # even though we assigned it as "b = a" instead it was pointing to the object 10 # which is # the same as writing b = 10.

List

与Swift和其他类似语言的行为相同。这是巨大的差异,让我们尝试更改某个索引处的值(这会变得更加棘手)

list1 = [10,20,30,40]
list2 = list1 #[10,20,30,40]

list1 = [3,4] 

# list1 ==> [3,4]
# list2 ==> [10,20,30,40]


它们都更改,因为它们都指向同一个对象,因此更改对象会同时更改所有list1 = [10,20,30,40] list2 = list1 #[10,20,30,40] # change value of list 1 at a certain index say index 0 list1[0] = 500 # If you check again the values of list1 and list2 you will be surprised. #list1 ==> [500,20,30,40] #list2 ==> [500,20,30,40] list1。这与其他语言(例如Swift)非常混淆。在Swift List / Array中是值类型,意味着它们没有被引用而是被复制,但是在python中则是另一回事,在某个索引处更改值会导致引用该对象的所有属性的值都更改,就像在上面的例子。对于来自Swift或其他类似语言的人来说,记住这一点非常重要。

那我们如何在python中复制?

  • 如果要使用python复制列表,则必须显式地这样做,如下面的示例所示:-
list2

list1 = [10,20,30,40] list2 = list(list1) # list1 ==> [10,20,30,40] # list2 ==> [10,20,30,40] 更改list1保持不变时,这样做可以避免不希望的影响。

例如

list2