在下面的例子中,一个类“自动”通过“引用”和一个变量“按值”传递:
class Q:
def __init__(self, q):
self.q = q
p = 42
q = Q(42)
def p_worker(p):
p += 1
return p
def q_worker(q):
q.q += 1
return q
print p is p_worker(p)
print q is q_worker(q)
输出结果为:
False
True
为何会出现这种差异?
答案 0 :(得分:4)
他们总是以同样的方式传递。 (这种方式有时称为"逐个调用"有时称为"按值调用,其中值为参考"。您可以在此处查看其他问题。)区别在于两个对象是什么以及你对它们做了什么。
p += 1
实质上告诉p
对象自己执行+= 1
,然后将结果分配给变量p
。整数无法更改其值,因此所有这一切都是向p
添加一个并将结果分配给p
。 p
是一个简单的名字" (即,只是一个简单的变量),所以这只是将数字43绑定到变量p
并将其绑定。
q.q += 1
告诉q.q
自己+= 1
,并将结果分配给q.q
。整数再次无法更改其值,因此这会将q.q
添加一个。但是q.q
不是一个简单的名字;它是一个属性引用。所以"分配给q.q
"表示"要求对象q
将此新值分配给其q.
属性"。由于q
可以更改其值(即其属性的值,但确实如此)。
最重要的是,您不能假设代码中的差异是因为参数传递语义在两种情况下是不同的。参数传递的作用相同。但是,传递的对象是不同的(一个是整数,一个是Q
),这些对象可以以不同的方式处理+=
之类的操作。这种差异不是在两种论证传递之间,而是在处理+=
的两种不同方式之间。