一个python3.x代码演示:
def fun():
global x
y.append(6)
x = 6
x = 3
y = [3]
print(x, y, fun(), x, y)
段输出:
3 [3, 6] None 6 [3, 6]
如果print()
过程计算所有项目,然后输出项目,那么这就解释了为什么fun()
和fun()
之后的y
结果都是[3, 6]
的,就像它们在这里一样。但是,为什么函数前后x
的值fun()
不同呢?
调用函数(如示例中的函数print
)时,参数将从左到右计算。
您的调用两次x
为参数。第一个使用原始值进行评估,3
。然后调用fun()
,这会产生更改全局变量x
的副作用。之后再次评估x
时,将获得更新的值6
。
如果您对所有参数使用函数调用,可能会更清楚一些,因为这也可以让你打印一些输出:
def get_x():
print("x is", x)
return x
def change_x():
global x
x += 1
print("x changed")
x = 0
print("args evaluated left to right:", get_x(), change_x(), get_x())
其输出为:
x is 0
x changed
x is 1
args evaluated left to right: 0 None 1
这个链接很好地解释了变量赋值。 https://nedbatchelder.com/text/names.html:
事实:Python 通过赋值来传递函数参数。 例如:
def fn(a):
pass
x = 10
当我们说fn(x)
时,它将是a = x
。另一个规则是从左到右计算参数。
说完这两个规则后,让我以与我们的示例匹配的特定方式重写 print 函数:
def print_(var1, var2, var3, var4, var5, sep=' ', end='n'):
sys.stdout.write(str(var1) + sep)
sys.stdout.write(str(var2) + sep)
sys.stdout.write(str(var3) + sep)
sys.stdout.write(str(var4) + sep)
sys.stdout.write(str(var5) + sep)
sys.stdout.write(end)
print_(x, y, fun(), x, y)
Python 将全局x
的值保存在局部变量var1
中。
var1 = x # `x` is 3 now
fun()
函数执行后,全局中的x
变为6
,但点是var1
仍然是3而不是6:
var1 = x = 3
x = 6
print(var1) # 3
。print_
将使用它的局部变量(var1
不是x
)。
但是从现在开始,每当Python看到x
时,它就会存储6
。 所以var4
是6。
var4 = x # `x` is 6 now
但是由于y
是一个列表,并且您更改了列表,因此var2
和y
都看到了变化!因为它们都指向同一个对象:
var2 = y = [3]
y.append(6)
print(var2) # [3, 6]
该函数print
复制局部变量中的参数,但每个参数都是不同的局部变量,并且从左到右计算。给你的台词print( x, y, func(), x, y)
会发生什么是这样的:
1.x 在局部变量中求值和复制。xLocal1 = x = 3
2.在局部变量中计算和复制 y。yLocal1 = [3]
3.Func() 被评估,它x
和ALLyLocal1
和y
发生变化,因为有一个global x
指定它仅适用于全局变量而不是局部变量。x = 6, yLocal1 = [3,6], y = [3,6]
.它从上一步更改变量
4.x 在 xLocal2 中被评估和复制。xLocal2 = x = 6
5.y 在 yLocal2 中被评估和复制。yLocal2 = y = [3,6]
6.它最终打印出所有等于3, [3,6], 6, [3,6]
的局部变量xLocal1, yLocal1, xLocal2 and yLocal2