【发布时间】:2015-01-04 01:10:10
【问题描述】:
我们都知道全局变量不好的教条。当我开始学习 python 时,我读到传递给函数的参数在函数中被视为局部变量。这似乎至少是事实的一半:
def f(i):
print("Calling f(i)...")
print("id(i): {}\n".format(id(i)))
print("Inside f(): i += 1")
i += 1
print("id(i): {}".format(id(i)))
return
i = 1
print("\nBefore function call...")
print("id(i): {}\n".format(id(i)))
f(i)
计算结果为:
Before function call...
id(i): 507107200
Calling f(i)...
id(i): 507107200
Inside f(): i += 1
id(i): 507107232
正如我现在所读到的,Python 中函数的调用机制是“通过对象引用调用”。这意味着参数最初是通过它的对象引用传递的,但是如果在函数内部对其进行了修改,则会创建一个new对象变量。避免函数无意修改全局变量的设计对我来说似乎是合理的。
但是如果我们将列表作为参数传递会发生什么?
def g(l):
print("Calling f(l)...")
print("id(l): {}\n".format(id(l)))
print("Inside f(): l[0] += 1")
l[0] += 1
print("id(l): {}".format(id(l)))
return
l = [1, 2, 3]
print("\nBefore function call...")
print("id(l): {}\n".format(id(l)))
g(l)
这会导致:
Before function call...
id(l): 120724616
Calling f(l)...
id(l): 120724616
Inside f(): l[0] += 1
id(l): 120724616
正如我们所见,对象引用保持不变!所以我们处理一个全局变量,不是吗?
我知道我们可以通过将列表的副本传递给函数来轻松克服这个问题:
g(l[:])
但我的问题是:在 Python 中实现两种不同的函数参数行为的原因是什么?如果我们打算操作一个全局变量,我们也可以像对待整数一样使用“全局”关键字来表示列表,不是吗?这种行为如何与python“显式胜于隐式”的禅相一致?
【问题讨论】:
-
感谢您的提示,即使经过大量搜索,我也没有找到此帖子。我的问题得到了回答。
-
TL;DR:它们没有区别对待,但
list对象是可变的 和int对象是不可变,它们的行为似乎不同。
标签: python function parameters globals