python:变量什么时候通过引用传递,什么时候通过值传递?

Python : When is a variable passed by reference and when by value?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Python: How do I pass a variable by reference?

我的代码:

1
2
3
4
5
6
locs = [ [1], [2] ]
for loc in locs:
    loc = []

print locs
# prints => [ [1], [2] ]

为什么loc不引用locs的元素?

python:除非显式复制,否则所有内容都作为引用传递[这不是真的吗?]

请解释一下……python如何决定引用和复制?

更新:

如何做?

1
2
3
4
5
6
def compute(ob):
   if isinstance(ob,list): return process_list(ob)
   if isinstance(ob,dict): return process_dict(ob)

for loc in locs:
   loc = compute(loc)  # What to change here to make loc a reference of actual locs iteration ?
  • LOC必须包含最终处理的响应!
  • 我不想使用enumerate,没有它是可能的吗?


effbot(又名fredrik lundh)将python的变量传递样式描述为按对象调用:http://effbot.org/zone/call-by-object.htm

对象在堆上分配,指向它们的指针可以在任何地方传递。

  • 当您进行诸如x = 1000之类的赋值时,将创建一个字典条目,该条目将当前命名空间中的字符串"x"映射到指向包含1000的整数对象的指针。
  • 当使用x = 2000更新"x"时,将创建一个新的整数对象,并更新字典以指向新对象。旧的一千个对象是不变的(可能还活着,也可能不活着,这取决于是否有其他的对象)。
  • 当您执行新的赋值(如y = x时,将创建一个新的字典条目"y",该条目指向与"x"条目相同的对象。
  • 像字符串和整数这样的对象是不可变的。这仅仅意味着在创建对象之后,没有方法可以更改它。例如,一旦创建了整数对象1000,它将永远不会改变。数学是通过创建新的整数对象来完成的。
  • 像列表这样的对象是可变的。这意味着可以通过指向对象的任何内容来更改对象的内容。例如,x = []; y = x; x.append(10); print y将打印[10]。已创建空列表。"x"和"y"都指向同一列表。append方法改变(更新)列表对象(如向数据库添加记录),结果对"x"和"y"都可见(就像数据库更新对该数据库的每个连接都可见一样)。

希望你能澄清这个问题。


Python中的所有东西都是通过值传递和赋值的,就像用Java中的值传递和赋值一样。python中的每个值都是对象的引用(指针)。对象不能是值。赋值总是复制值(即指针);这样两个指针就可以指向同一个对象。对象永远不会被复制,除非您正在做一些显式的复制。

对于您的情况,循环的每次迭代都会将列表的一个元素分配给变量loc。然后再为变量loc赋值。所有这些值都是指针;您正在分配指针;但是您不会以任何方式影响任何对象。


在python中,从引用或值的角度考虑是没有帮助的。两者都不正确。

在Python中,变量只是名称。在for循环中,loc只是一个指向列表中当前元素的名称。执行loc = []只需将名称loc重新绑定到不同的列表中,而不必使用原始版本。

但是,由于在您的示例中,每个元素都是一个列表,因此您实际上可以改变该元素,这将反映在原始列表中:

1
2
for loc in locs:
    loc[0] = loc[0] * 2


当你说

1
loc = []

您正在将loc变量重新绑定到新创建的空列表中。

也许你想要

1
loc[:] = []

它将loc的一个切片(恰好是整个列表)分配给空列表


Why is loc not reference of elements of locs ?

它是。或者至少,它在某种意义上与Python中的其他所有变量是相同的。python变量是名称,而不是存储。loc是用来指[[1,2], [3,4]]的元素的名称,而locs是指整个结构的名称。

1
loc = []

这并不意味着"看看loc命名的东西,然后让它变成[]"。这并不意味着,因为Python对象不具备这样的能力。

相反,它的意思是"使loc停止成为它当前的名称,而开始成为[]的名称"。(当然,它意味着这里提供的特定[],因为一般来说,内存中可能有几个相同的对象。)

因此,locs的含量自然保持不变。


一切都是由对象传递的。重新绑定和变异是不同的操作。

1
2
3
4
5
locs = [ [1], [2] ]
for loc in locs:
    del loc[:]

print locs