为什么python全局范围受本地范围操作的影响?

时间:2013-01-26 19:38:39

标签: python scope

我认为传递给python函数的变量的更改仍保留在函数的本地范围内,并且不会传递给全局范围。但是当我写一个测试脚本时:

#! /usr/bin/python
from numpy import *

def fun(box, var):
    box[0]=box[0]*4
    var=var*4
    return 0

ubox,x = array([1.]), 1.
print ubox,x
fun(ubox,x)
print ubox,x

输出结果为:

[myplay4]$ ./temp.py 
[ 1.] 1.0
[ 4.] 1.0

整数变量x不受函数内部操作的影响,但是数组是。列表也会受到影响,但只有在列表/数组切片上操作时才会发生这种情况。

有人可以解释为什么本地范围在这种情况下会传递到全球范围吗?

4 个答案:

答案 0 :(得分:2)

在你的功能中

def fun(box, var):
    box[0]=box[0]*4
    var=var*4
    return 0

boxvar都是本地的,更改它们不会更改其在调用范围中的值。但是,这一行:

box[0]=box[0]*4

不会改变box;它会更改box引用的对象。如果该行写为

box = box[0]*4 + box[1:]

然后调用范围中的box确实会保持不变。

答案 1 :(得分:2)

要实现的重要一点是,当将对象传递给函数时,该函数不能与该对象的独立副本一起使用,它可以使用同一个对象。因此,对象的任何更改都是外部可见的。

您说局部变量的更改仍然是本地的。这是真的,但它只适用于改变变量(即重新分配它们)。它不适用于变异变量所指向的对象。

在您的示例中,您重新分配var,因此外部无法看到更改。但是你正在改变box(通过重新分配其中一个元素)。这种变化在外面可见。如果您只是重新指定box来引用其他对象(box = something),则该更改将无法在外部显示。

答案 2 :(得分:1)

这与范围完全没有关系。

您正在将对象传递给函数。在该函数内部,该对象发生了变异。关键是函数内部的变量引用与调用函数中相同的对象,因此更改在外部可见。

答案 3 :(得分:-2)

这不取决于范围。这取决于Python如何复制对象。在这方面,有三种对象:标量,可变对象,不可变对象。

Scalars按值复制,可变对象通过引用复制,不可变对象可能通过引用复制,但由于您无法修改它们,因此没有任何含义。

Scalars是所有数字类型的例子。不可变的是:字符串和元组。可变的是:列表,词典和其他对象。