Jupyter调用Python函数时提示'b_threshold'未定义的问题解决
问题原因
h_b_acc函数里直接引用了b_threshold、a_threshold、mul三个变量,但这些变量不在函数的本地作用域内:
- 在multi.py的
if __name__ == '__main__':块运行时,变量属于模块全局作用域,和函数同属一个作用域,所以能正常访问 - 在Jupyter Notebook调用时,你定义的变量是Notebook的全局变量,和multi模块的函数作用域不共享,函数找不到这些变量,因此抛出未定义错误
另外注意:原代码里pp.get(['mul'],200)是写法错误,get方法的第一个参数应该是字符串键名,正确写法是pp.get('mul',200),这个错误在所有方案里都需要修正。
解决办法
方案1:将参数作为函数入参传入(最规范)
这是Python函数设计的最佳实践,让函数依赖明确,避免隐式依赖全局变量。
修改multi.py的函数:
import json def h_b_acc(data, har={}, b_threshold=2, a_threshold=5, mul=200): trr = data.tt.unique() for tr in trr: temp_dict = {} temp_df = data.loc[data['tt']==tr].copy() temp_df['b_event'] = temp_df['aci'].apply(lambda x: 1 if x < b_threshold else 0) temp_df['a_event'] = temp_df['aci'].apply(lambda x: 1 if x > a_threshold else 0) total_d_dis = temp_df['dd'].max() - temp_df['dd'].min() temp_dict['b_s'] = (2015* mul)/ total_d_dis temp_dict['a_s']= (2016 * mul)/ total_d_dis har['tr_' + str(tr)] = temp_dict return har if __name__ =='__main__': try: with open(r'path\par.json', "r") as prm_mp: pp = json.load(prm_mp) # 示例调用(需自行准备tm数据) # har_result = h_b_acc(tm, b_threshold=pp['b_threshold'], a_threshold=pp['a_threshold'], mul=pp['mul']) except Exception as e: print(f"参数文件解析失败: {str(e)}")
Jupyter Notebook调用代码:
import json import multi with open(r'path\par.json', "r") as prm_mp: pp = json.load(prm_mp) # 调用时传入读取到的参数 har_1 = multi.h_b_acc(tm, b_threshold=pp['b_threshold'], a_threshold=pp['a_threshold'], mul=pp['mul']) har_1
方案2:让函数内部直接读取配置文件
如果不想每次调用都传参,可以让函数自己读取par.json,减少外部代码重复:
修改multi.py的函数:
import json def h_b_acc(data, har={}): # 函数内部读取配置,失败则用默认值 try: with open(r'path\par.json', "r") as prm_mp: pp = json.load(prm_mp) b_threshold = pp.get('b_threshold', 2) a_threshold = pp.get('a_threshold', 5) mul = pp.get('mul', 200) except Exception as e: print(f"参数文件解析失败,使用默认值: {str(e)}") b_threshold = 2 a_threshold =5 mul=200 trr = data.tt.unique() for tr in trr: temp_dict = {} temp_df = data.loc[data['tt']==tr].copy() temp_df['b_event'] = temp_df['aci'].apply(lambda x: 1 if x < b_threshold else 0) temp_df['a_event'] = temp_df['aci'].apply(lambda x: 1 if x > a_threshold else 0) total_d_dis = temp_df['dd'].max() - temp_df['dd'].min() temp_dict['b_s'] = (2015* mul)/ total_d_dis temp_dict['a_s']= (2016 * mul)/ total_d_dis har['tr_' + str(tr)] = temp_dict return har if __name__ =='__main__': # 直接调用即可(需自行准备tm数据) # har_result = h_b_acc(tm) pass
Jupyter Notebook调用代码:
import multi # 直接调用,函数会自行处理参数读取 har_1 = multi.h_b_acc(tm) har_1
方案3:使用模块全局变量(不推荐,易引发问题)
如果一定要用全局变量的方式,需要把变量定义在multi模块的全局作用域,而非仅在main块内:
修改multi.py:
import json # 初始化全局参数默认值 b_threshold = 2 a_threshold =5 mul=200 # 加载配置覆盖默认值 try: with open(r'path\par.json', "r") as prm_mp: pp = json.load(prm_mp) b_threshold = pp.get('b_threshold', 2) a_threshold = pp.get('a_threshold', 5) mul = pp.get('mul', 200) except Exception as e: print(f"参数文件解析失败,使用默认值: {str(e)}") def h_b_acc(data, har={}): # 声明使用模块全局变量 global b_threshold, a_threshold, mul trr = data.tt.unique() for tr in trr: temp_dict = {} temp_df = data.loc[data['tt']==tr].copy() temp_df['b_event'] = temp_df['aci'].apply(lambda x: 1 if x < b_threshold else 0) temp_df['a_event'] = temp_df['aci'].apply(lambda x: 1 if x > a_threshold else 0) total_d_dis = temp_df['dd'].max() - temp_df['dd'].min() temp_dict['b_s'] = (2015* mul)/ total_d_dis temp_dict['a_s']= (2016 * mul)/ total_d_dis har['tr_' + str(tr)] = temp_dict return har if __name__ =='__main__': # 直接调用即可(需自行准备tm数据) # har_result = h_b_acc(tm) pass
Jupyter Notebook调用代码:
import multi # 直接调用,模块已加载好全局参数 har_1 = multi.h_b_acc(tm) har_1
内容的提问来源于stack exchange,提问作者Sushil Kokil
相关产品推荐
相关产品推荐

