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

why is python global scope affected by local scope operations?

我认为传递给python函数的变量的更改仍保留在函数的本地作用域中,而不传递给全局作用域。但当我写测试脚本时:

1
2
3
4
5
6
7
8
9
10
11
12
#! /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

输出为:

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

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

在这种情况下,有人能解释为什么本地作用域会传递到全局作用域吗?


要认识到的重要一点是,当将对象传递给某个函数时,该函数不与该对象的独立副本一起工作,而是与同一对象一起工作。所以对对象的任何更改都可以从外部看到。

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

在您的示例中,您重新分配了var,因此在外部看不到更改。然而,您正在对box进行变异(通过重新分配它的一个元素)。这种变化在外面是可见的。如果您只是将box重新分配为引用不同的对象(box = something),那么该更改在外部将不可见。


在你的职能范围内

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

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

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

不改变box;改变box所指的对象。如果那句话写得像

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

那么,调用作用域中的box实际上将保持不变。


这完全与范围无关。

您正在将一个对象传递给一个函数。在这个函数中,对象是可变的。关键是函数中的变量引用的对象与调用函数中的对象相同,因此这些更改在外部可见。


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

scalar是按值复制的,可变对象是按引用复制的,不可变对象可能是按引用复制的,但由于不能修改它们,因此没有任何含义。

scalar是所有数字类型的前示例。不可变的是:字符串和元组。可变的是:列表、字典和其他对象。