简体   繁体   中英

Global Name Not Defined in Python

Am new to Python OOP. Please dont be harsh. Here is my code which calculates which is the fastest time of an athlete from a list and displays them. But When Running, I get this error:

z= add.mylist.min()
NameError: global name 'add' is not defined

My Code:

class Athlete:

    def add(self):
        list=[]
        mylist=[]

        for i in range(2):

            self.name = raw_input("Enter name: ")
            self.fastest_time = input("time: ")
            list.append(self.name)
            mylist.append(self.fastest_time)
        print "Names: ",list
        print "Fastest times: ",mylist

    def display(self):
        z= add.mylist.min()
        w= add.mylist.index(z)
        print "Minimum time: ",z
        print "Name of athelte with fastest time: ",list[w]

x = Athlete()
x.add()
x.display()

You need to refer to methods on the instance with the self parameter. In addition, your add() method needs to return the mylist variable it generates, you cannot refer to method local variables as attributes on methods:

def display(self):
    mylist = self.add()
    z = min(mylist)
    w = mylist.index(z)

def add(self):
    list=[]
    mylist=[]

    for i in range(2):

        self.name = raw_input("Enter name: ")
        self.fastest_time = input("time: ")
        list.append(self.name)
        mylist.append(self.fastest_time)
    print "Names: ",list
    print "Fastest times: ",mylist

    return mylist

That is what self is for , as a reference point to find instance attributes and other methods on the same object.

You may want to rename list to something that does not shadow the built-in type.

Martijn has already answered your question, so here are some remarks and code style tips:

  1. New-style classes derive from object
  2. You have both athlete names and their times, those belong together as key-value pairs in a dictionary instead of two separate lists
  3. Don't use print statements inside class methods, a class method should return an object that you then can print
  4. what if you have more then 2 athletes for which you want to enter the time? If you make the number of athletes an argument of your function, you can add a variable number of athlethes
  5. give descriptive variable names (not mylist ) and don't use names of builtin functions (like list ) as variable name
  6. variables that you want to use throughout your class can be initalized in an __init__ method.
  7. For printing, use the format function instead of using commas
  8. use if __name__ == '__main__' so that your Python file can act as either reusable modules or as standalone program

Taking these into account, I would rewrite your code to something like this:

from collections import defaultdict

class Athlete(object): # see (1)
    def __init__(self): # see (6)
        self.athlete_times = defaultdict(str) # see (2)

    def add_athletes_and_times(self, n): # see (4)
        for i in range(n):
            self.name = raw_input("Enter name: ")
            self.fastest_time = input("time (in seconds): ") 
            self.athlete_times[self.fastest_time] = self.name

    def get_fastest_time(self):
        return min(self.athlete_times) # see (3)

if __name__ == '__main__': # see (8)
    x = Athlete()
    x.add_athletes_and_times(2)
    for fast_time in x.athlete_times:
        print "The fastest time of athlete {0} is {1} seconds.".format(
                        x.athlete_times[fast_time], fast_time) # see (7)
    fastest_time = x.get_fastest_time()
    print "The overall fastest time is: {0} seconds for athlete {1}.".format(
                       fastest_time, x.athlete_times[fastest_time])

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