我刚刚查看了我不久前编写的一些代码,并注意到全局变量有些奇怪。例如,在update_board
中,我将board
作为参数传递,并在函数中更新它,但不返回更新的板,但它仍然会更新。所以看起来我基本上是在为board
使用全局值。
为了保持一致性,我是否应该避免传递board
参数并改用global board
?我知道全局变量不被鼓励,但至少对他们明确一点可能更好。还是用board = update_board(board, row, col)
替换update_board(board, row, col)
实例并从update_board
返回board
更好?
还是我可能偶然发现了一种有效的方法,因为代码是存在的?
"""
Chomp - a strategy game
"""
import random
import time
NUM_ROWS = 5
NUM_COLS = 6
FILLED_SPOT = "#"
POISON_SPOT = "P"
EMPTY_SPOT = " "
def print_title():
print(r"""
______ __ __ ______ __ __ ______
/ ___ / _ / __ / "-./ / ==
____ __ / -./ _-/
_____ _ _ _____ _ _ _
/_____/ /_//_/ /_____/ /_/ /_/ /_/
""")
def print_instructions():
print("Welcome to Chomp. Choose a square. All squares to the right")
print("and downwards will be eaten. The computer will do the same.")
print("The one to eat the poison square loses. Good luck!")
print()
def who_goes_first():
return random.choice(("computer", "human"))
def play_again():
print("Would you like to play again (yes or no)?")
return input().lower().startswith("y")
def print_matrix(matrix):
for row in matrix:
for elem in row:
print(elem, end=EMPTY_SPOT)
print()
def validate_user_input(player_choice, board):
try:
row, col = player_choice.split()
except ValueError:
print("Bad input: The input should be exactly two numbers separated by a space.")
return False
try:
row = int(row)
col = int(col)
except ValueError:
print("Input must be two numbers, however non-digit characters were received.")
return False
if row < 0 or row > NUM_ROWS - 1:
print(f"The first number must be between 0 and {NUM_ROWS - 1} but {row} was passed.")
return False
if col < 0 or col > NUM_COLS - 1:
print(f"The second number must be between 0 and {NUM_COLS - 1} but {col} was passed.")
return False
if board[row][col] == EMPTY_SPOT:
print("That square has already been eaten!")
return False
return True
def update_board(board, row, col):
for i in range(row, len(board)):
for j in range(col, len(board[i])):
board[i][j] = EMPTY_SPOT
def get_human_move(board):
valid_input = False
while not valid_input:
player_choice = input("Enter the row and column number (counting from 0) of your choice,
nseparated by a space: ")
valid_input = validate_user_input(player_choice, board)
row, col = player_choice.split()
return int(row), int(col)
def get_computer_move(board):
valid_move = False
while not valid_move:
row = random.randint(0, NUM_ROWS - 1)
col = random.randint(0, NUM_COLS - 1)
if board[row][col] == EMPTY_SPOT:
continue
else:
valid_move = True
return row, col
def main():
game_over = False
while not game_over:
board = []
for i in range(NUM_ROWS):
row = []
for j in range(NUM_COLS):
row.append(FILLED_SPOT)
board.append(row)
board[0][0] = POISON_SPOT
game_is_playing = True
turn = who_goes_first()
print_title()
print_instructions()
print_matrix(board)
print()
while game_is_playing:
if turn == "human":
# Human turn
print("Human turn.")
row, col = get_human_move(board)
if board[row][col] == POISON_SPOT:
print()
print("Too bad, the computer wins!")
game_is_playing = False
else:
update_board(board, row, col)
print()
print_matrix(board)
print()
turn = "computer"
time.sleep(1)
else:
# Computer turn
row, col = get_computer_move(board)
print(f"Computer turn. The computer chooses ({row}, {col})")
print()
if board[row][col] == POISON_SPOT:
print()
print("Yay, you win!")
game_is_playing = False
else:
update_board(board, row, col)
print_matrix(board)
print()
turn = "human"
if play_again():
main()
else:
print("Goodbye!")
game_over = True
main()
您没有全局变量。相反,你有一个本地范围的变量,你可以传递给你的函数。
创建变量时,只需创建一个别名以指向对象的内存位置。在下面的代码中,我们将创建一个列表,它是一个对象,里面有一个字符串对象。然后,我们创建名称 mylist 并将其指向列表对象的内存位置。
mylist = [1]
然后,当您将 mylist 传递给函数时,发生的情况是函数获取 mylist 指向的内存位置的副本,并且函数将其局部变量设置为指向该内存位置。
因此,当您执行一个操作来改变该内存位置中的对象时,该更新也将通过函数外部的变量名称看到,因为两者都指向相同的内存位置。
但是,如果您要将 soemthing 重新分配给函数中的该变量,例如创建新列表,那么这不会反映在函数外部的变量中。由于实际发生的是创建一个新对象,并且局部范围变量将指向它。这不会更改函数外部变量的内存地址,该变量仍指向原始位置。
def first():
mylist = [1]
print("mylist:", mylist)
print("mylist id:", id(mylist))
second(mylist)
third(mylist)
print("mylist:", mylist)
print("mylist id:", id(mylist))
def second(second_list):
#here the local function variable second_list points to the same memory location as mylist
print("second id:", id(second_list))
#Here we change the values in this memory location. So second list is still pointing to and change the data that my list points to
#this is why mylist can see the change even though its not a global variable
second_list.append(2)
print("Second_list:", second_list)
print("second id:", id(second_list))
def third(third_list):
#here the local function variable third_list points to the same mermoy location as mylist
print("third list:", third_list)
print("third id:", id(third_list))
#here we create a new object which will have a new memory lcaotion then we point the local variable third_list at it.
#now third_list points to new memory location and not the same memory location as mylist.
third_list=[3]
print("third list:", third_list)
print("third id:", id(third_list))
first()
下面是输出,您可以在其中看到每个对象的内存 ID,您将看到它们如何指向同一对象,然后在第三个函数中将其重定向到内存中的新对象。
mylist: [1]
mylist id: 2636457271880
second id: 2636457271880
Second_list: [1, 2]
second id: 2636457271880
third list: [1, 2]
third id: 2636457271880
third list: [3]
third id: 2636457271944
mylist: [1, 2]
mylist id: 2636457271880