【发布时间】:2014-02-05 19:00:03
【问题描述】:
这似乎是一个非常愚蠢的问题,但我对 Python 中的范围规则感到困惑。在下面的示例中,我将两个带有值的变量 (x,y) 发送到一个应该更改其值的函数。当我打印结果时,变量没有改变。
def func1(x,y):
x=200
y=300
x=2
y=3
func1(x,y)
print x,y #prints 2,3
现在,如果这是 C++,我将通过引用 (&) 将它们发送到该函数,因此能够更改它们的值。那么 Python 中的等价物是什么?更重要的是,当您将对象发送到函数时实际发生了什么? Python 是否对这些对象进行了新的引用?
【问题讨论】:
-
所有 Python 名称是对对象的引用。函数参数仅绑定到传入的对象。您没有获得内存位置,在表达式中使用它时总是取消引用该名称。赋值是重新绑定,而不是改变原来的内存位置。因此
x = 200正在创建一个新对象(int(200)),并将对该对象的引用存储在x中。 -
内部作用域具有从外部作用域访问变量的隐式权限,但需要从外部作用域修改变量的显式权限。我可以说得非常简洁。
-
(CPython 可以选择在此处重用现有的
int()对象,但这是一个实现细节)。 -
因此,尽管
func1内部的本地名称x和y开始与模块范围内的全局x和y名称绑定到相同的int()对象,通过在函数内部分配给它们,您只会反弹本地名称。全局名称仍然引用它们的原始值。