繁体   English   中英

为什么一个变量是全局访问的,而另一个变量不在 Python 中?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM