在我的(简化)脚本中,我有以下内容:
def predict(new_data):
.
.
.
model_list = fetch_needed_models() # ["f1","f2","f3"]
for m in model_list:
with open(f"./{m}.pkl","rb") as file:
exec(f"{m}=pickle.load(file)")
print(dir()) # [...,'f1','f2','f3',...]
# Try with list-comprehension
f1_pred = [f1.predict(x) for x in new_data] # NameError: name 'f1' does not exists
# Try with loop
f1_pred = []
for x in new_data:
f1_pred.append(f1.predict(x)) # NameError: name 'f1' does not exists如果我在函数之外运行这些行,即只一个接一个地运行这些行(在VScode中,交互式窗口中),它可以很好地工作,但是当我像python main.py一样运行这个函数时,会得到一个NameError: name 'f1' is not defined错误。我认为可能exec没有正确执行,但是在exec命令之后的print(dir())显示,变量确实存在。
有人知道为什么吗?
编辑
一个简单的测试,比如
def test():
exec("f= []")
f.append(2)
print(f)
if __name__=="__main__":
test()> python test.py
> "NameError: name "f" is not defined也失败了
发布于 2022-06-22 14:09:36
如果您确实想使用exec (您不应该使用,并且应该重构代码以避免它),那么您必须传递要在其中执行代码的环境。使用简化的示例,您可以这样做:
def test():
exec("f= []", globals())
f.append(2)
print(f)
if __name__=="__main__":
test() # [2]发布于 2022-06-22 14:10:17
局部变量是编译时特性;即使使用exec,也不能在运行时将真正的局部变量添加到函数中。编译时,计算局部变量的固定大小数组的大小,并在该数组中为每个名称分配一个索引;数组不能展开,无法识别的名称没有映射。您可以使用locals() (它复制真正的局部变量,然后是一个可以变异的dict )来伪造它,但是不要。
只需使用由您所关心的名称组成的dict键:
def predict(new_data):
.
.
.
model_list = fetch_needed_models() # ["f1","f2","f3"]
models = {}
for m in model_list:
with open(f"./{m}.pkl","rb") as file:
models[m] = pickle.load(file)
# Try with list-comprehension
f1_pred = [models['f1'].predict(x) for x in new_data]
# Try with loop
f1_pred = []
for x in new_data:
f1_pred.append(models['f1'].predict(x))如果您知道f1总是存在于其中,您可以直接提取它,但是这种方法违背了动态指定模型的目的:
def predict(new_data):
.
.
.
model_list = fetch_needed_models() # ["f1","f2","f3"]
models = {}
for m in model_list:
with open(f"./{m}.pkl","rb") as file:
models[m] = pickle.load(file)
# We're sure f1 will be there, so we can make it a local manually
f1 = models['f1']
# Try with list-comprehension
f1_pred = [f1.predict(x) for x in new_data]
# Try with loop
f1_pred = []
for x in new_data:
f1_pred.append(f1.predict(x))https://stackoverflow.com/questions/72716045
复制相似问题