简体   繁体   中英

NameError: name 'playerNumber' is not defined - even though i defined it in another function

Im coding a snake game for a project but for some reason it says that the variable playerNumber is not defined even though i very clearly defined it in the previous function. I dont really know whats wrong and i have tried various things and nothing has helped.

import turtle
gt = turtle.Turtle()
t1 = turtle.Turtle()
t2 = turtle.Turtle()
t3 = turtle.Turtle()
t4 = turtle.Turtle()
turtle.bgcolor("White")

def start():
    print ("Welcome to python Snake! A game made by Kippo and inspired by the famous game: Snake!")
    playerNumber = int(input("How many players are going to play? (2-4)"))
    if playerNumber >= 5:
        print("Too many players! Try again.")
        start()
    elif playerNumber <= 1:
        print("Too few players! Try again.")
        start()
    else:
        playerColour()
        
def playerColour():
    global playerNumber
    if playerNumber == 1:
        player1colour = input("player 1, what colour do you want to be?")
    elif playerno == 2:
        player1colour = input("player 1, what colour do you want to be?")
        player2colour = input("player 2, what colour do you want to be?")
    elif playerno == 3:
        player1colour = input("player 1, what colour do you want to be?")
        player2colour = input("player 2, what colour do you want to be?")
        player3colour = input("player 3, what colour do you want to be?")
    elif playerno == 4:
        player1colour = input("player 1, what colour do you want to be?")
        player2colour = input("player 2, what colour do you want to be?")
        player3colour = input("player 3, what colour do you want to be?")
        player4colour = input("player 4, what colour do you want to be?")
    else:
        print ("Too many players, try again.")
        quit()
        
def gridSize():
    gridsize = int(input("What size do you want your grid to be?"))
    gt.circle(2)
    


start()

I have tried changing the name of the variable, moving the functions around, and trying various other methods of using the variable and nothing has changed.

Let's talk about scope.

You wrote this:

def start():
    playerNumber = ...

def playerColour():
    global playerNumber
    if playerNumber == ...

That is, start() makes an assignment, and playerColor() hopes to read that value. But as written, it's making an assignment that is local to start .

Put a global playerNumber declaration within start , and you will see different behavior.


scope

Python maintains variable namespaces at different levels of visibility, including "top level" and "local to a function" such as start() or playerColour().

A reference to a name will probe a few namespaces in sequence, matching a function's local variables before the top level global variables.

An assignment in a function will usually create a local variable, which goes out-of-scope (it is destroyed) upon exiting the function.

A common "gotcha" in python looks like this:

name = "Alice"

def set_name():
    name = "Bob"

set_name()
print(name)

Question: what will this display?

Answer: Alice. Why? Because when we set the name, we created a new local variable. Which we then never used, and it was destroyed when the function exited.

To obtain the intended behavior, declare a global:

def set_name():
    global name
    name = "Bob"

In practice, most code will prefer to encapsulate such code and data within a class, assigning to self.name instead. But that's a topic for another day.


global variables

You are just starting out programming, and I applaud that, go for it, keep hacking.

I will just point out that once you've written a couple of programs, having debugged and maintained them, you will start to see why most folks view lots of global variables as a problem-waiting-to-happen, a source of coupling we try to design out of our systems from the onset.

Python and other languages offer features which seek to reduce needless coupling, scoping variables down so it's clear which bits of code they affect. Function arguments help to address that need. Defining a class can be a big part of the solution.

Friend mentioned the problem related to scope.You can fix the problem by doing what he said.

As a second way, you can give the playerNumber variable, where you store the value you get from the user, as a parameter to the function you use. This will be a safer way to declare a global variable

def playerColour(playerNumber:int):
       // some logic


def start():
    print ("Welcome to python Snake! A game made by Kippo and inspired by the famous game: Snake!")
    playerNumber = int(input("How many players are going to play? (2-4)"))
    if playerNumber >= 5:
        print("Too many players! Try again.")
        start()
    elif playerNumber <= 1:
        print("Too few players! Try again.")
        start()
    else:
        playerColour(playerNumber)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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