我试图访问函数中的全局变量,但它似乎认为它是NoneType。有帮助吗? 该错误似乎相信字典'学生'是NoneType,即使我告诉它,它也不是将它作为全局变量读取。这是我的代码的错误或是这个版本的python的问题,我无法复制任何其他程序的错误(使用2.7-3.3.3版本!)
#Imports
from math import floor
#Global Declarations (for later)
#Functions
def loadData():
"""Loads the students.txt file if it exists."""
studentsFile = open("students.txt", "r")
data = studentsFile.read()
students = exec(data)
studentsFile.close()
return students
def fileExists():
"""Checks if the students.txt file exists."""
try:
studentsFile = open("students.txt", "r")
studentsFile.close()
students = loadData()
except FileNotFoundError:
studentsFile = open("students.txt", "w")
studentsFile.close()
students = {}
print(students)
return students
def saveToFile():
global students
studentsFile = open("students.txt", "w")
studentsFile.write(str(students))
studentsFile.close()
def gradeCalc(score):
possibleGrades = {"A*" : [x for x in range(90, 101)], "A" : [x for x in range(80, 90)], "B" : [x for x in range(70, 80)], "C" : [x for x in range(60, 70)], "D" : [x for x in range(50, 60)], "E" : [x for x in range(40, 50)], "F" : [x for x in range(30, 40)], "G" : [x for x in range(20, 30)], "U" : [x for x in range(0, 20)]}
for key in possibleGrades:
if int(floor(score)) in possibleGrades[key]:
grade = key
def studentExists(studentName):
global students
print(students)
print(studentName)
try:
testVar = students[studentName]
return True
except KeyError:
return False
def doneTest(studentName, testName):
try:
testVar = students[studentName][testName]
return True
except KeyError:
return False
def integerInput(msg):
while True:
try:
integer = int(input(msg))
return integer
except ValueError:
print("Not a whole number.")
def scoreInput():
while True:
studentScore = integerInput("Enter the students score: ")
if studentScore <= 100 and studentScore >= 0:
break
else:
print("Not between (and including) 0 and 100.")
return studentScore
def getData():
global students
quantity = integerInput("How many students do you wish to add? ")
test = str(input("Please enter a test name: ").lower())
for i in range(0, quantity):
name = str(input("Student name: ").title())
score = scoreInput()
if studentExists(name) == False:
students[name] = {}
students[name][test] = score
students[name][test+"Grade"]=gradeCalc(score)
def displayData():
global students
studentsToDisplay = []
listOfGrades = []
print("You must choose a mode. How many students got each grade or the grades for an individual student.")
mode = input("Please select 'grade' or 'student'").lower()
if mode == 'grade':
test = str(input("For which test do you want to access the grades for? ").lower())
for key in students:
if doneTest(key, test)==True:
studentsToDisplay.append(key)
for item in studentsToDisplay:
listOfGrades.append(students[item][test+"Grade"])
print("Grades:\nA*:", ListOfGrades.count("A*"), "\nA:", ListOfGrades.count("A"), "\nB:", ListOfGrades.count("B"), "\nC:", ListOfGrades.count("C"), "\nD:", ListOfGrades.count("D"), "\nE:", ListOfGrades.count("E"), "\nF:", ListOfGrades.count("F"), "\nG:", ListOfGrades.count("G"), "\nU:", ListOfGrades.count("U"))
elif mode == "student":
studentName = str(input("Student name: ").title())
test = str(input("Test name: ").lower())
if doneTest(studentName, test) == True:
print(studentName, "got", students[studentName][test], "and this is grade:", students[studentName][test+"Grade"])
def main():
global students
students = fileExists()
while True:
choice = str(input("Do you want to add students/tests or do you want to review previous data? (accepts 'add' and 'review') ").lower())
if choice == "add":
getData()
saveToFile()
elif choice == "review":
displayData()
else:
exitChoice = str(input("Do you want to exit? ").lower())
if exitChoice == "yes" or exitChoice == "y":
break
main()
我收到此错误:
Traceback (most recent call last):
File "V:\GCSE 2013\sj.sully\Programme Library\Assessed Tasks and CAT Practice\CAT Practice Scenario 1 Code.py", line 108, in <module>
main()
File "V:\GCSE 2013\sj.sully\Programme Library\Assessed Tasks and CAT Practice\CAT Practice Scenario 1 Code.py", line 100, in main
getData()
File "V:\GCSE 2013\sj.sully\Programme Library\Assessed Tasks and CAT Practice\CAT Practice Scenario 1 Code.py", line 71, in getData
if studentExists(name) == False:
File "V:\GCSE 2013\sj.sully\Programme Library\Assessed Tasks and CAT Practice\CAT Practice Scenario 1 Code.py", line 39, in studentExists
testVar = students[studentName]
TypeError: 'NoneType' object is not subscriptable
我正在使用python 3.3.0。
答案 0 :(得分:1)
好吧,如果students
为无,那是因为您在使用之前没有定义students
。
但是使用全局变量来解决这个问题是疯狂的。实际上,使用全局变量是邪恶的,不应该这样做。
Python是一种OOP语言,因此您应该使用正确的工具来完成正确的任务。 对于您的特定用例,您可以使用类,例如:
class StudentsData:
def __init__(self):
self.students = []
def loadData(self):
pass
def fileExists(self):
pass
def save(self):
pass
def scoreInput(self):
pass
def display(self):
pass
但是有些函数不适合在类中使用,例如:
def gradeCalc(score):
pass
def main():
pass
我没有给你实现,因为你需要尝试和失败来了解如何进行正确的OOP设计。我很确定你也在做计算机编程课程,所以请阅读你关于这个主题的课程! ; - )
编辑:要阅读有关该主题的更多信息,请参阅以下SO答案中的资源列表:
编辑#2:我能想到的唯一例外是“全局是邪恶的”规则,用于声明常量(即你不会修改的变量),所以你可以将它们全部定义在你的一个地方程序。我已经读过人们倾向于使用state / env对象作为全局变量,这可以被视为单例,并且很容易被认为是糟糕的编程。在做这样的事情之前你需要三思而后行,因为经常使用一个类可能是一个更好的解决方案......
另外,如果您阅读python的源代码,您将找到使用全局变量的示例。但它不会是在python中不经意间实现的唯一可怕的东西...