Python 3中exec调用对象赋值时出现语法错误求助
问题描述
使用shelve读取对象后,尝试通过exec动态为对象赋值时出现语法错误,代码如下:
with shelve.open(obj_path) as obj: for as_num in obj['as_number_list']: # obj['as_number_list'] 是列表 temp = charge_as(obj['as_' + str(as_num)]) # temp 是 instruments.AS 实例 as_test = temp # 直接赋值正常 print(type(as_test)) exec("as_{}_obj = {}".format(as_num, temp)) # 此处报错
执行后抛出语法错误:
<class 'instruments.AS'> Traceback (most recent call last): File "...", line 45, in <module> exec("as_{}_obj = {}".format(as_num, temp)) File "<string>", line 1 as_1_obj = <instruments.AS object at 0x000002A86732E290> ^ SyntaxError: invalid syntax
改用temp.__dict__后无报错,但生成的as_{}_obj是字典类型,而非原instruments.AS类实例:
exec("as_{}_obj = {}".format(as_num, temp.__dict__))
问题原因
- 直接在
exec字符串中拼接temp时,Python会把对象转换成它的字符串表示形式(即repr(temp)),也就是<instruments.AS object at 0x...>,这不是合法的Python赋值语法,因此触发语法错误。 - 使用
temp.__dict__时,拼接的是对象属性字典的字符串,exec执行后会创建一个新字典,自然丢失了原对象的类类型。
解决方案
方法1:避免使用exec(推荐)
直接通过globals()全局命名空间字典动态赋值,既安全又能保留对象类型:
with shelve.open(obj_path) as obj: for as_num in obj['as_number_list']: temp = charge_as(obj['as_' + str(as_num)]) globals()[f'as_{as_num}_obj'] = temp # 直接将对象存入全局命名空间
方法2:正确使用exec
如果一定要用exec,不要直接拼接对象,而是让exec引用当前作用域中的temp变量,通过传递全局命名空间参数实现:
with shelve.open(obj_path) as obj: for as_num in obj['as_number_list']: temp = charge_as(obj['as_' + str(as_num)]) exec(f"as_{as_num}_obj = temp", globals())
这里exec的第二个参数globals()指定了执行环境,确保temp能被正确解析为当前作用域中的对象实例。
内容的提问来源于stack exchange,提问作者mag non
相关产品推荐
相关产品推荐

