Python读取文本文件为变量赋值时文本值触发NameError错误的技术问询
解决exec赋值字符串时的NameError问题
你碰到的这个坑其实很好理解——当你用exec给变量赋值的时候,数字类型(比如22101)能直接生效,是因为Python会把它识别为数值常量;但字符串tom就不一样了,你直接把它放进exec语句里,Python会把它当成变量名去查找,而不是字符串字面量,这就触发了NameError。
问题出在哪
看你的代码生成的exec语句:
处理第一行时,生成的是exec("zip = 22101")——这没问题,22101是数值常量;
处理第二行时,生成的是exec("name = tom")——这里tom没有被引号包裹,Python会去寻找名为tom的变量,自然找不到就报错了。
几种解决方案
1. 给字符串值手动加引号
最简单的修改方式,就是在格式化exec语句时,给值加上单引号:
import os File_InputApi = "c:\\temp\\File_InputApi.txt" Handle_InputApi = open(File_InputApi, 'r') for Line_InputApi in Handle_InputApi: var_InputApi = Line_InputApi.split('=>')[0].strip() val_InputApi = Line_InputApi.split('=>')[1].strip() # 给值加上单引号,把它变成字符串字面量 exec("%s = '%s'" % (var_InputApi,val_InputApi)) print(zip) print(name) Handle_InputApi.close()
这样第二行就会生成name = 'tom',Python就会把'tom'当成字符串赋值给name了。不过要注意,如果你的值本身包含单引号,这种方式会出问题,需要额外处理转义。
2. 用字典存储变量(更安全推荐)
其实尽量别用exec,因为如果输入文件内容不可控,会有安全风险。更稳妥的方式是用一个字典来存储所有变量:
import os File_InputApi = "c:\\temp\\File_InputApi.txt" # 用字典存储变量 config_vars = {} # 用with语句自动关闭文件,更规范 with open(File_InputApi, 'r') as Handle_InputApi: for Line_InputApi in Handle_InputApi: var_InputApi = Line_InputApi.split('=>')[0].strip() val_InputApi = Line_InputApi.split('=>')[1].strip() # 自动识别数值类型,失败则保留字符串 try: val_InputApi = int(val_InputApi) except ValueError: try: val_InputApi = float(val_InputApi) except ValueError: pass config_vars[var_InputApi] = val_InputApi # 通过字典访问变量 print(config_vars['zip']) print(config_vars['name'])
这种方式不仅安全,还能自动区分数值和字符串,完全避免exec的语法问题。
3. 用ast.literal_eval安全解析值
如果一定要用类似exec的方式,推荐用ast.literal_eval来解析值,它只会处理合法的Python字面量,比直接exec安全得多:
import ast import os File_InputApi = "c:\\temp\\File_InputApi.txt" with open(File_InputApi, 'r') as Handle_InputApi: for Line_InputApi in Handle_InputApi: var_InputApi = Line_InputApi.split('=>')[0].strip() val_InputApi = Line_InputApi.split('=>')[1].strip() # 用literal_eval解析,自动识别类型 try: parsed_val = ast.literal_eval(val_InputApi) except ValueError: # 如果不是合法字面量,就当成字符串处理 parsed_val = ast.literal_eval(f"'{val_InputApi}'") exec(f"{var_InputApi} = parsed_val") print(zip) print(name)
内容的提问来源于stack exchange,提问作者hdsouza
相关产品推荐
相关产品推荐

