You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3.6中列表与numpy数组默认是全局变量吗?为何函数内表现不同?

解惑:Python中可变/不可变对象与变量作用域的区别

嘿,这个问题其实是Python里可变对象和不可变对象以及变量作用域规则共同作用的结果,咱们一步步拆解清楚:

首先先看你给出的代码:

import numpy as np
x=np.array([1,2])
y=[1,2]
L=1
def set_L(x,y,L):
    x[0]+=1
    y[0]+=1
    L+=1
    print(id(x))
    print(id(y))
    print(id(L))

核心概念先理清

  • 可变对象:比如列表、numpy数组、字典这类,它们的内部元素可以被直接修改,修改操作不会改变变量指向的对象(也就是id不变)。
  • 不可变对象:比如整数、字符串、元组这类,一旦创建就无法修改内部值,所谓的“修改”其实是创建一个新的对象,然后让变量指向这个新对象(id会改变)。

为什么x、y的id和全局变量一致?

你在函数里对x和y做的操作是x[0]+=1和y[0]+=1——这属于原地修改可变对象的内部元素,并没有给x或y这个变量重新赋值新的对象。

Python的作用域规则里,当你在函数内操作一个变量的内部元素(而不是给变量赋值)时,会先去全局作用域找这个变量对应的对象,找到后直接修改对象内容。所以函数里的x、y和全局的x、y指向的是同一个对象,自然id完全一致。

这绝对不是说列表和数组默认是全局变量,换个场景:如果你在函数里写x = np.array([3,4]),这就是给函数内的x变量重新赋值了,此时它就变成了局部变量,id会和全局的x不一样。

为什么L的id和全局变量不一样?

L是整数,属于不可变对象。你在函数里做L+=1,本质是创建了一个值为2的新整数对象,然后把函数内部的L变量指向这个新对象。

这个时候,函数里的L是一个局部变量——因为你对它做了赋值操作,Python会默认在函数内部创建一个新的局部变量,和全局的L完全是两个不同的变量,所以它们的id自然不一样。

如果想让函数里的L操作全局的那个,只需要在函数开头加global L声明,这样L+=1就会修改全局的L变量指向的对象(不过因为整数不可变,还是会创建新对象,但此时函数里的L和全局的是同一个变量)。

一句话总结

不是列表/数组默认是全局变量,而是你对它们做的是原地修改可变对象的操作,没有重新赋值变量;而对不可变的L做的是赋值操作,触发了局部变量的创建,这才导致了id的差异。

内容的提问来源于stack exchange,提问作者Liang Xiao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:05:22