Python中的词汇作用域

Python中的词汇作用域,python,scoping,Python,Scoping,我正在学习Python,更具体地说,我正在探索范围规则 我尝试了以下“实验”: 这段代码输出:2,1。既然变量n被返回到全局环境,它不应该输出2,2吗 非常感谢您的建议。这里有两个不同的变量(名称):一个位于全局范围内,另一个位于增量的本地。在increment中重新绑定本地一个不会影响全局一个,而increment返回它自己的n也不会影响全局一个(它们具有相同名称的事实是无关的)。如果要使全局n指向increment()返回的值,必须明确地重新绑定它: n = 1 print(n) n = i

我正在学习Python,更具体地说,我正在探索范围规则

我尝试了以下“实验”:

这段代码输出:2,1。既然变量n被返回到全局环境,它不应该输出2,2吗


非常感谢您的建议。

这里有两个不同的变量(名称):一个位于全局范围内,另一个位于
增量的本地。在
increment
中重新绑定本地一个不会影响全局一个,而
increment
返回它自己的
n
也不会影响全局一个(它们具有相同名称的事实是无关的)。如果要使全局
n
指向
increment()
返回的值,必须明确地重新绑定它:

n = 1
print(n)
n = increment(n)
print(n)

考虑对上述代码段的以下修改:

def increment(n): 
   n[0] += 1 
   print(n[0])
   return n

n = [1] 
increment(n) 
print(n[0]) 
这是2,2

在许多计算机语言(其中包括Javascript)中,基本函数参数(如整数1和2)或复合函数参数(如单元素列表n[0])之间存在差异。通常原语按值传递(它们的值复制到函数内部的临时变量)。复合实体通常不被复制,而是通过引用传递(实体的地址被传递,实体从函数中被访问)。如果我看一下上面两段代码的输出,在我看来Python也起到了作用


PS在我写了这篇文章之后我看了。在2009年最流行的答案中,基本实体被称为不可变对象,复合实体被称为可变对象,否则我的答案与旧答案一致。

return
的意思不是“在此之后,将范围更改为全局”,而是表达式的值
increment(n)
将成为本地n。因此,您应该做
n=increment(n)
,这是您需要知道的一切。相关的可能重复:Python没有基本类型,一切都是对象,易变性映射不好(例如,元组是不可变的复合实体)。此外,所有参数都是通过对象引用传递的,既不是值也不是引用:作为Python新手,我想知道如何合理化使用标量n调用函数increment()或使用列表[n]调用函数increment()的差异。差别是不可否认的,2,1或2,2都是印刷品。Jornsharpe,你知道怎么解释吗?你确实在做不同的事情。在一个例子中,您正在变异一个可变的数据结构:
n[0]=n[0]+1
(请注意,当您变异参数时返回一些东西是非常不寻常的)。在另一个例子中,您将名称从一个不可变对象重新分配到另一个新的不可变对象:
n=n+1
-1正如已经观察到的,这个答案是不正确的。与原帖子类似的是,将
n
重新分配给一个新列表,
n=[2]
increment
中(代替
n[0]+=1
)。这也将输出与原始帖子一致的
2
1
def increment(n): 
   n[0] += 1 
   print(n[0])
   return n

n = [1] 
increment(n) 
print(n[0])