[英]Why one variable is accessed globally and other is not in Python?
我正在尝试实现一个简单的 BFS 代码。
代码:
def initalizeVertex():
n = int(input('Enter the no. of vertices.\n'))
for vertex in range(n):
Vertex.append(vertex)
node_adjacency[vertex] = []
def initalizeUndirectedEdges():
n = int(input("Enter the no. of edges.\n"))
print("Enter the space seperated edges.")
for i in range(n):
a,b = map(int,input().split())
node_adjacency[a].append(b)
node_adjacency[b].append(a)
def bfs():
current_level = 1
print(Vertex)
while(current_level_nodes):
for current_node in current_level_nodes:
for child_node in node_adjacency[current_node]:
if node_parent.get(child_node) == None:
node_parent[child_node] = current_node
next_level_nodes.append(child_node)
node_level[child_node] = current_level
current_level_nodes = [node for node in next_level_nodes]
next_level_nodes = []
current_level += 1
print(node_level)
print(node_parent)
def printData():
print(Vertex)
print(node_adjacency)
print(node_parent)
print(node_level)
print(current_level_nodes)
print(next_level_nodes)
if __name__ == "__main__":
root = 0
Vertex = []
node_adjacency = {}
node_parent = {root:None}
node_level = {root:0}
current_level_nodes = [root]
next_level_nodes = []
initalizeVertex()
initalizeUndirectedEdges()
printData()
bfs()
代码 output 是:
这段代码给了我错误:
in bfs
while(current_level_nodes):
UnboundLocalError: local variable 'current_level_nodes' referenced before assignment
显然, bfs()
function 无法访问列表current_level_nodes
。 我可以通过将列表current_level_nodes
传递给bfs
function 来解决这个问题。
但是,我的问题是,当我没有将列表Vertex
传递给initalizeVertex()
function 时,为什么我必须将此列表传递给bfs()
function,而 ZC1C425268E68385D1AB507 仍然可以修改它?
此外,我还没有将任何参数传递给printData
function 但是 function 打印所有列表和字典而没有给出任何错误。
Python 将尝试在本地 scope 1st 中查找变量。 如果在本地找不到它们,Python 将在全球范围内寻找它们。
例如 -
在您的 printData() function - Python 将尝试在本地查找变量,但在此方法中未定义任何变量。 所以,Python 将 go 在全局 scope。 它将选择值并打印它们。
def printData():
print(Vertex)
print(node_adjacency)
print(node_parent)
print(node_level)
print(current_level_nodes)
print(next_level_nodes)
在另一个 function bfs() -
Python 会在一段时间内看到 current_level_nodes,Python 会尝试查找变量的定义位置。 由于您稍后在 function 中分配了相同的变量,因此事情会变得棘手。 这会混淆 Python,并且会抛出错误。
line 1. - while(current_level_nodes):
line 2. - current_level_nodes = [node for node in next_level_nodes]
这就是为什么您需要明确告诉 Python 您要使用全局变量 -
global current_level_nodes
The issue here involves the python compiler having compiled the rest of your function and it realizing that it must bind your variables within the function. 这需要前面提到的global
关键字。
这里令人困惑的是,错误显示在第一次使用变量时,而不是实际问题所在。 这是一个例子:
access_only.py:
global_list = [1,2,3]
def f():
for x in global_list:
print(x)
f()
在这里,我们运行它:
$python access_only.py
1
2
3
现在我们稍微更改 function 以包括对列表的分配,就像您的代码中那样。
access_and_change.py:
global_list = [1,2,3]
def f():
for x in global_list:
global_list = [1, 2, 3]
print(x)
f()
在这里我们运行它,但即使问题实际上发生在global_list =
行上,也会在for
行上出现错误:
$python access_and_change.py
Traceback (most recent call last):
File "access_and_change.py", line 9, in <module>
f()
File "access_and_change.py", line 4, in f
for x in global_list:
UnboundLocalError: local variable 'global_list' referenced before assignment
最终结果是相同的,因为您正在为列表分配值,所以必须使用global
关键字。 如果您消除 function 中的分配,则错误将完全消失。
考虑到这一点,我注意到错误消息说在分配之前引用了局部变量。 我认为这里的问题是因为 function 包含一个赋值,所以变量被认为是本地的。 而如果您只是引用一个全局变量,则它不被视为局部变量。 因此,赋值导致变量被视为本地变量,并且在您第一次引用它时,python 会抛出此错误,而不是搜索全局/父命名空间,因为编译器已经确定它必须是局部变量。
您必须以这种方式在 bfs function 中定义 current_level_nodes 是全局的:
def bfs():
current_level = 1
global current_level_nodes
...
编辑:要访问 function 中的全局变量,无需使用 global 关键字。 但是,如果我们需要为全局变量分配新值或更改它,那么我们可以通过将变量声明为全局变量来实现。 因为你用过
next_level_nodes.append(child_node)
和
current_level_nodes = [node for node in next_level_nodes]
您需要使用全局; 如果您没有修改 function 中的 current_level_nodes ,则无需使用 global
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.