今天在写基本统计值的例程的 时候,发现了一个很奇怪的写法,如下:
#tongjijisuan
from math import*
def getNum():
nums = []
iNumStr = input("请输入数字(直接输入回车退出):") #这里
while iNumStr != "":
nums.append(eval(iNumStr))
iNumStr = input("请输入数字(直接输入回车退出)") #这里
return nums
已经直接在while下面写入了获取输入的程序了,为什么还要先在while循环上面再写一个给iNumStr获取用户输入值的程序?
这样写进去不是多余的吗?
而且如果用户第一个输入值若就是回车,就会报错了。
于是我删了while上面的给iNumStr获取输入值的代码:
结果出现了:
======================== RESTART: D:/python/cishi3.py ========================
Traceback (most recent call last):
File "D:/python/cishi3.py", line 15, in <module>
n = getNum()
File "D:/python/cishi3.py", line 5, in getNum
while iNumStr != "":
UnboundLocalError: local variable 'iNumStr' referenced before assignment
>>>
报错的意思大概就是,变量再使用前没有被声明。
错误原因:
再获取iNumStr之前已经用了它,但前面还没有定义,因此会出现这样的问题。
在查资料的过程中,还发现里几个同样会出现这样的报错的坑,在这里总结一下。
第二种:
def xiao():
if xxx == 23:
xxx = 24
xxx = 23
xiao()
print(xxx)
UnboundLocalError: local variable 'xxx' referenced before assignment
错误原因:
依旧是使用变量前为声明或定义它。
为什么呢?前面不是已经定义了 xxx = 23 了吗,为什么还会声明未定义?
其实是全局变量与局部变量搞混了,在函数外部声明的变量是全局变量,在函数内部的是局部变量。全局变量和局部变量即使名字一样,但是,他们是却是两个不同的变量,是不相同的。
那么如何在函数内部使用全局变量呢?
这就需要用到global了,在局部量之前加上global声明其是全局变量即可。
正确示例:
def xiao():
global xxx
if xxx == 23:
xxx = 24
xxx = 23
xiao()
print(xxx)
输出为24.
第三种:在内层函数调用外层函数没有使用nonlocal时:
def fun1():
x = 5
def fun2():
x *= 2
print(x)
fun2()
fun1()
执行内层函数fun2时,由于没有定义x,所以也会出现报错。fun1是外层函数,fun2是内层函数。每一层函数的变量若没有声明都是不同的。
那么,如果内层函数想要修改外层函数(不是全局变量)的变量时,应该如何操作呢?这就需要用到nonlocal了。
正确示例:
def fun1():
x = 5
def fun2():
nonlocal x
x *= 2
print(x) #输出 10
fun2()
print(x) #输出 10,被内层函数修改而一致
fun1()
另外,还需要记住python变量引用顺序:
从当前作用域开始寻找变量,如果没找到就往上一层作用域寻找,没找到就再上一层…即:
当前作用域局部变量->外层作用域变量->再外层作用域变量->…->当前模块全局变量->pyhton内置变量
global和nonlocal的区别:
global:全局变量
nonlocal:外层嵌套函数的变量
1、局部作用域改变全局变量用global, global同时还可以定义新的全局变量
2、内层函数改变外层函数变量用nonlocal, nonlocal不能定义新的外层函数变量,只能改变已有的外层函数变量 同时nonlocal不能改变全局变量
总结未定义的三大坑:
坑1:先使用后定义(往往在判断时)而报错
坑2:局部变量想调用全局变量未声明global
坑3:内层函数调用外层函数未声明nonlocal