python变量作用域和生存期_看一个Python变量作用域的问题
这个起源于我逛社区看到一个人的提问,本质上就是变量作用域的问题。scores = {‘语文’:89, ‘数学’:95, ‘英语’:80}sum_score = 0def get_average(scores):for subject, score in scores.items():sum_score += scoreprint(‘现在的总分是%d’%sum_score)ave_score = s
这个起源于我逛社区看到一个人的提问,本质上就是变量作用域的问题。
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
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
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)