Python 更改列表元素与更改列表本身
我有一个关于变量的名称范围的问题,我试图在这里找到答案,我得到了一个类似的答案,但仍然有点困惑 因此,代码如下:Python 更改列表元素与更改列表本身,python,variables,scope,Python,Variables,Scope,我有一个关于变量的名称范围的问题,我试图在这里找到答案,我得到了一个类似的答案,但仍然有点困惑 因此,代码如下: position = [50, 50] # Handler for timer def tick(): x = random.randrange(0, width) y = random.randrange(0, height) position[0] = x position[1] = y 在这里,为什么我不需要添加“全局位置”来更改可变位置的
position = [50, 50]
# Handler for timer
def tick():
x = random.randrange(0, width)
y = random.randrange(0, height)
position[0] = x
position[1] = y
在这里,为什么我不需要添加“全局位置”来更改可变位置的元素 只有在分配全局位置变量以引用新列表时才需要添加全局位置(如果没有全局声明,位置将写入函数的局部变量中) 在您的情况下,您所做的只是查找全局变量位置,以找到它所引用的列表。然后,您将更新该列表 下面是一个显示所有变体的列表(分配给本地、分配给全局、更新全局引用的列表) 另外,请看一看Ned Batchelder的文章,其中充分解释了python的对象传递机制。From- 如果某个变量在代码块中使用,但未在代码块中定义,则该变量为自由变量 从— global语句是一个声明,用于保存整个当前代码块。这意味着列出的标识符将被解释为全局标识符。如果没有全局变量,就不可能分配给全局变量,,尽管自由变量可能引用全局变量而不声明为全局变量。 (强调矿山) 当你这样做的时候-
position[0] = <something>
position[0] = <something>
您将得到namererror
-
>>> position[0] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'position' is not defined
>位置[0]=1
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
名称错误:未定义名称“位置”
这就是为什么,即使您执行了position[0]=
,它仍然是一个自由变量,因为它没有在块中定义,因此它被视为全局变量
更新: 更多信息,当你这样做-
position[0] = <something>
position[0] = <something>
位置[0]=
这不是一个,实际上是一个。您需要应用两个概念来理解代码
- Python对象模型
- 范围界定
x=1000
,将发生以下步骤
- 创建值为1000的int对象
- 已创建对象引用
x
指向该整数对象x
tick()
内执行语句position[0]=x
时,该语句不具有仅初始化部分的赋值。由于位置
未在函数范围内定义,因此它会按作用域规则的层次结构顺序进行查找-封闭范围(父函数)后跟模块范围(文件),后跟内置模块。在这里,它在全局范围内找到变量并更新它
如果您的语句是position=[100100]
,则将创建一个新的列表对象,并在tick()函数的作用域内创建新的对象引用并执行赋值
若有
global position
语句,它会告诉Python全局范围内的变量和局部范围内的变量相同。随后是position=[100100]
创建一个列表对象[100100]
,并将其全局变量position
链接到新的列表对象。那么您的意思是position元素会自动更新,而无需将其声明为全局?我有点难以接受这个概念…是的。这样想吧。假设您有一个名为position的全局变量,它是与数据库的连接。您可以在不使用全局声明的情况下查找该变量(因为没有同名的局部变量)。然后可以使用该连接修改数据库,但不更改连接本身。什么时候需要全球宣言?仅当您正在为位置分配新连接时。在第一种情况下,位置保持不变,数据库更改。在第二种情况下,position被更改为另一个连接。谢谢,但是我怎么知道我最初提供的cod是哪种情况的呢?那么你的意思是position的元素会自动更新,而无需声明为global?我有点难以接受这个概念…谢谢,但我还是有点困惑,所以你说当我做“位置[0]=x”时,对象位置在全局范围内是可用的,我同意这一点,但是当我做“位置=[100100]”时,对象位置在全局范围内不是仍然可用吗?它为什么会创建一个新对象?@Enkri\ux,当执行position=[100100]
时,初始化和赋值都会发生。因此,位置在局部范围内定义,并发生赋值。当执行位置[0]=x
时,仅发生赋值。它不进行初始化,而是按照作用域规则的层次结构开始搜索,在全局范围内找到匹配项并进行更新。我更新了我的答案以反映同样的情况,