Python函数内使用外部全局变量为何未抛异常且可正常运行?
问题原因解答
你对Python作用域的判断有误,Python的变量查找遵循LEGB规则,优先级从高到低依次是:
- L(Local,局部作用域):函数内部定义的变量、入参
- E(Enclosing,闭包外层作用域):嵌套函数的外层函数作用域
- G(Global,全局作用域):当前Python文件顶层定义的变量
- B(Built-in,内置作用域):Python内置的变量/函数,比如
int、sum等
你在函数内部使用y_model和y_test时,首先会在局部作用域查找,没找到就会自动向上查找全局作用域的变量,这两个值刚好是你在当前文件顶层定义的全局变量,所以可以正常读取,不会抛出异常。
注意:你当前的写法存在明显的逻辑bug:函数入参明明定义了
y_predict和y_actual,但内部完全没有使用,而是硬编码读取全局的y_model和y_test,后续如果调用函数时传入其他参数,函数运行时依然会用全局的两个值,完全不会响应入参的变化。
另外你原有代码还有一个隐藏错误:直接对两个Python列表做==比较,返回的是单个布尔值(判断两个列表是否完全相等),而不是你预期的逐元素比较的布尔数组,最终输出的TP只能是0或者1,不符合计算召回率、精确率的逻辑。修正后的正确写法参考:
import numpy as np y_model=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,1,1 ,0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 ,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1] y_test=[0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0 ,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1 ,0,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,1 ,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1] def return_recall_and_precision(y_predict,y_actual): # 转成numpy数组后才支持逐元素比较,返回布尔数组 y_predict_np = np.array(y_predict) y_actual_np = np.array(y_actual) # 用传入的参数而非全局变量,保证函数通用性 TP = (y_predict_np == y_actual_np) print("tp is", TP) TP = np.sum(TP) return TP TP = return_recall_and_precision(y_model, y_test) print(TP)
内容的提问来源于stack exchange,提问作者onion117
相关产品推荐
相关产品推荐

