模块化程序设计中将一个大的程序按功能划分成若干个小程序模块,常用的方法就是将某个确定的功能封装为一个函数,对外提供接口,在其他模块中只需导入该模块即可调用。为了得到确定的结果,对函数返回值的检查显得尤为重要。
问题的发现: 一次作业中,需设计一个学生成绩录入系统,先确定所要录入学生成绩的数量,之后动态地输入学生的信息。输入之前需要检查输入的学生数量是否为数值型,若不是将会影响到后续信息的输入。
由于涉及到错误输入的校正,首先想到的是 try: …… except:……
语句,并且如果输入有误需要重复输入,因此需要循环输入与判断。采用的是模块化设计,自然是用函数来实现。程序输入次数不确定可以通过while
循环判断,但递归似乎也是个不错的选择(我也不太确定下面的程序是否属于递归 = =)初步的函数编写如下:
def inputnum():
"""check the input and return the count"""
try:
count = int(input("请输入需要录入的学生数量:"))
return count
except:
print("请输入正确的学生数量!(数字形式)")
inputnum()
int()
将输入的数值型数据转为十进制,若用户的输入为空或含有非数值型的数据,将引发错误,被except
子句捕捉,提示用户重新输入正确数据。并且返回数值类型的 count 变量,作为后面动态输入学生信息的循环条件。看似正常,可在运行中却出现Traceback:TypeError: ‘NoneType’ object cannot be interpreted as an integer 显然函数的返回值并不是count,而是None。
分析可知,若用户起初输入的就是正确数据,程序运行正常,而错误输入之后的改正将引发上述错误,因为错误输入程序将进入except
子句,重新正常输入返回的是count,退出except子句中的inputnum()函数,但未退出except
子句,在未指明返回值时,默认返回None,None无法转为其他类型数据,自然就会引发上述错误了。
Python函数未指明返回值,默认返回值为None,与单独的return语句等同。
return
=return None
若是在except子句中也加入return count 呢?结果是:UnboundLocalError: local variable ‘count’ referenced before assignment 变量在引用前还未定义,这里是针对count这个变量的。由于Python是门弱类型语言,不对变量赋值是无从知晓变量的类型的。给变量赋初值这里又有个问题,在函数内部还是外部?
若是在函数内部对count变量赋初值0(即定义),当程序进入except子句时后续信息录入过程将直接跳过(也即返回的count值为0,未进入循环)。如果是在函数外部定义,也将出现上述变量在引用前还未定义的问题。其实就是局部变量与全局变量的冲突:函数外部定义的变量为全局变量,函数内为局部变量,若局部变量与全局变量重名,对变量进行修改,就会将其变为局部变量,从而引发上述错误。
而在except子句中加入return 语句为何count值不改变呢?其实就回到第一个问题了,想想递归函数的调用和返回次序就明白了。如果想在函数内部引用全局变量就需要使用global
关键字,最终代码如下:
def inputnum():
"""check the input and return the count"""
global count
try:
count = int(input("请输入需要录入的学生数量:"))
except:
print("请输入正确的学生数量!(数字形式)")
inputnum()
return count
至此问题解决!