Python简单成绩程序无法访问全局变量,触发NameError: 'marks'未定义
问题根因排查
核心问题本质是Python的作用域规则:所有需要跨函数读写的全局变量,每一个要对该变量做赋值操作的函数,都必须单独用global关键字声明关联到全局作用域,不能因为一个函数里声明过全局,其他函数就自动继承这个关联。
具体代码错配点
对照你写的流程逐段拆解:
getInput()函数里虽然用global声明了Quiz、Ass、Test1、Test2、marks、Grade、GradePoint这些全局变量,但这个声明的生效范围仅局限在getInput()函数内部,和其他函数没有任何关联。- 进入
getGrades()函数后,你读取Quiz、Ass、Test1、Test2的值是可以正常拿到的——因为这几个值是getInput()写入到全局作用域的,且getGrades()里没有对这几个变量做重新赋值,Python会自动向外层作用域查找取值。但你对marks、Grade、GradePoint做了赋值计算,函数内却没有声明这几个是全局变量。根据Python规则,函数内只要对某个变量有赋值动作,整个函数作用域都会把该变量判定为局部变量——也就是说getGrades()里算出的marks、Grade、GradePoint全存在这个函数自己的局部内存里,函数执行结束后这部分内存就会被回收,根本没有写入全局空间。 - 执行到
showGrades()时,会去全局作用域寻找marks、Grade、GradePoint的值,但全局作用域里从来没被这几个变量被赋值过(getGrades里的赋值全在局部空间),因此直接抛出NameError: name 'marks' is not defined。
修复步骤
- 在
getGrades()函数的最开头补上全局变量声明:def getGrades(): # 新增这行声明,把函数内的变量操作关联到全局作用域 global Quiz, Ass, Test1, Test2, marks, Grade, GradePoint # 后面原本的计算逻辑保持不变 marks = float((Quiz * 0.2) + (Ass * 0.2) + (Test1 * 0.3) + (Test2 * 0.3)) # ... 后续的等级判断逻辑和原来完全一致 - 在
showGrades()函数的最开头补上全局变量声明,明确告诉Python要从全局作用域读取这几个值:def showGrades(): # 新增这行声明 global marks, Grade, GradePoint # 后面原本的打印逻辑保持不变 print(f"your overall marks are:" , float(marks)) # ... 后续打印逻辑和原来完全一致
补充规则提醒:如果函数内只是读取全局变量、不做任何赋值操作,可以省略
global声明;但只要函数内存在对该变量的赋值语句,就必须在函数开头加global声明,否则Python会把整个函数作用域内的该变量都判定为局部变量,哪怕读取的代码写在赋值语句前面也会触发报错。
内容的提问来源于stack exchange,提问作者Jagdeesh Kumar
相关产品推荐
相关产品推荐

