共计 1528 个字符,预计需要花费 4 分钟才能阅读完成。
这个起源于我逛社区看到一个人的提问,本质上就是变量作用域的问题。
scores = {'语文':89, '数学':95, '英语':80}
sum_score = 0
def get_average(scores):
for subject, score in scores.items():
sum_score += score
print('现在的总分是%d'%sum_score)
ave_score = sum_score/len(scores)
print('平均分是%d'%ave_score)
get_average(scores)
要是直接运行会报以下 的错误
Traceback (most recent call last): File “1.py”, line 11, in <module> get_average(scores) File “1.py”, line 6, in get_average sum_score += score UnboundLocalError: local variable ‘sum_score’ referenced before assignment
根据错误的类型发现是局部变量的问题导致的,这就扯到了变量作用域的问题。
如果你不对sum_score做赋值 的操作,你会发现在函数里直接打印或者干其他事都不会报错比如以下的
代码
def get_average_1(scores)
print(sum_score)
出现这种情况的根本原因在于 Python在编译的时候在函数的定义内发现你对这个变量赋值,默认就会在本地找定义,生成的字节码也会验证这个问题。所以会报上面的错误。
套用官方的说法,这不是缺陷,这是设计方式:Python 不要求你明确声明变量,但是假定函数体内赋值的变量都是局部变量。
顺便验证一下字节码吧,需要dis这个包
from dis import dis
print(dis(get_average))
你会看到以下 的结果
0 SETUP_LOOP 28 (to 30)
2 LOAD_FAST 0 (scores)
4 LOAD_ATTR 0 (items)
6 CALL_FUNCTION 0
8 GET_ITER
>> 10 FOR_ITER 16 (to 28)
12 UNPACK_SEQUENCE 2
14 STORE_FAST 1 (subject)
16 STORE_FAST 2 (score)
6 18 LOAD_FAST 3 (sum_score)
20 LOAD_FAST 2 (score)
22 INPLACE_ADD
24 STORE_FAST 3 (sum_score)
26 JUMP_ABSOLUTE 10
>> 28 POP_BLOCK
7 >> 30 LOAD_GLOBAL 1 (print)
32 LOAD_CONST 1 ('现在的总分是%d')
34 LOAD_FAST 3 (sum_score)
36 BINARY_MODULO
38 CALL_FUNCTION 1
40 POP_TOP
8 42 LOAD_FAST 3 (sum_score)
44 LOAD_GLOBAL 2 (len)
46 LOAD_FAST 0 (scores)
48 CALL_FUNCTION 1
50 BINARY_TRUE_DIVIDE
52 STORE_FAST 4 (ave_score)
9 54 LOAD_GLOBAL 1 (print)
56 LOAD_CONST 2 ('平均分是%d')
58 LOAD_FAST 4 (ave_score)
60 BINARY_MODULO
62 CALL_FUNCTION 1
64 POP_TOP
66 LOAD_CONST 0 (None)
68 RETURN_VALUE
这LOAD_FAST 3 (sum_score) 就是从本地去读取数据这样明显就会报错。
所以解决上述问题有两种解决方法:
1、函数内 global sum_score
2、函数内定义局部变量 sum_score
正文完
请博主喝杯咖啡吧!