Python 方法导致代码中断

35 阅读3分钟

我们有一个 Python 代码,用来计算一个迷宫的地图。迷宫由一个二维数组表示,其中 0 表示地板,999 表示墙壁,其他数字表示不同的房间。我们的目标是找到从起始位置到终点位置的最短路径。

以下是原来的代码:

floorMap = [[000,000,000,000,000,999,999,999,999,999],
           [000,000,999,000,999,000,000,000,999,999],
           [000,000,999,000,999,000,000,000,999,999],
           [000,000,000,000,999,000,000,000,999,999],
           [999,000,000,000,999,000,999,999,999,999],
           [999,000,000,000,000,000,999,000,000,999],
           [999,000,000,000,999,999,999,000,000,999],
           [999,000,999,000,000,000,999,000,000,999],
           [999,000,999,999,999,000,000,000,000,999],
           [999,999,999,999,999,999,999,999,000,000]]


currentNum=0

wall=999
uncalculated=000

robotX=0
robotY=0
goalX=9
goalY=9

floorMap[goalY][goalX]=1

def changeSurroundings(X, Y):

        #left
        if(floorMap[X-1][Y]==uncalculated and X > 0):
            floorMap[X-1][Y]=currentNum   
        #right 
        if(X < len(floorMap[0])-1 and floorMap[X+1][Y]==uncalculated):
            floorMap[X+1][Y]=currentNum  
        #up
        if(floorMap[X][Y-1]==uncalculated and Y > 0):
            floorMap[X][Y-1]=currentNum  
        #down
        if(Y < len(floorMap)-1 and floorMap[X][Y+1]==uncalculated):
            floorMap[X][Y+1]=currentNum    


def printMap():
    i=0
    floorMap[goalY][goalX]='G'
    floorMap[robotY][robotX]='R'

    while(i<len(floorMap)):
        print floorMap[i]
        print ""
        i+=1
    print ""
    print ""

#------------------MOST IMPORTANT CHUNK OF CODE--------------

while(floorMap[robotY][robotX]==uncalculated):
    x=0
    while(x<len(floorMap[0])):
        y=0
        while(y<len(floorMap)):
            if(floorMap[x][y] > uncalculated and floorMap[x][y] < wall):
                currentNum=floorMap[x][y]+1
                changeSurroundings(x,y)                                
            y+=1
        x+=1

printMap()

我们想把这段代码转换成一个方法,以便可以在其他地方重用。但是,当我们这样做的时候,代码就会中断。

def calcMap():  
    while(floorMap[robotY][robotX]==uncalculated):
        x=0
        while(x<len(floorMap[0])):
            y=0
            while(y<len(floorMap)):
                if(floorMap[x][y] > uncalculated and floorMap[x][y] < wall):
                    currentNum=floorMap[x][y]+1
                    changeSurroundings(x,y)                                
                y+=1
            x+=1

printMap()

2. 解决方案

问题出在全局变量上,特别是 currentNum。当我们把 calcMap 函数转换成一个方法时,currentNum 就变成了局部变量,而不再是全局变量。因此,当我们在方法中修改 currentNum 的值时,不会影响到 main 函数中的 currentNum 的值。

为了解决这个问题,我们需要使用全局变量。我们可以使用 global 关键字来声明一个变量是全局变量。

def calcMap():
    global currentNum
    while(floorMap[robotY][robotX]==uncalculated):
        x=0
        while(x<len(floorMap[0])):
            y=0
            while(y<len(floorMap)):
                if(floorMap[x][y] > uncalculated and floorMap[x][y] < wall):
                    currentNum=floorMap[x][y]+1
                    changeSurroundings(x,y)                                
                y+=1
            x+=1

printMap()

现在,当我们在 calcMap 方法中修改 currentNum 的值时,会影响到 main 函数中的 currentNum 的值。因此,代码就可以正常工作了。

我们还可以使用更加 Pythonic 的语法来编写 calcMap 函数:

def calc_map():
    for x, array in enumerate(floor_map):
        for y, element in enumerate(array):
            if uncalculated < element < wall:
                current_num = element + 1
                change_surroundings(x, y, current_num)

print_map()

使用这种语法,代码更加简洁和易读。