如何用exec创建全局类对象?globals()使用遇变量未定义问题
问题分析与解决
核心问题
- exec命名空间不匹配:给
exec传globals()后,exec执行的代码只能访问全局变量,但u、y、c是create_item函数内的局部变量,全局命名空间中不存在,因此触发"u未定义"错误。 - 编号逻辑错误:原代码一次性把
items_created加上要创建的总数量,循环创建对象时会重复使用同一个编号,导致后面的对象直接覆盖前面的实例。 - 动态全局变量不合理:用exec生成
it1这类全局变量,既容易引发命名冲突,也不方便后续统一管理这些对象。
修正方案
改用字典存储所有Item对象,同时修正计数逻辑,每创建一个对象就递增一次编号,彻底避开exec带来的问题。
修正后的代码
items_created = 0 # 用字典存储所有Item实例,键为对象编号(如"it1"),值为对应Item对象 items_store = {} class Item: def __init__(self, name: str, price: float, quantity=0): self.name = name self.price = price self.quantity = quantity print(f"'{self.name}' was added") def total_amount(self): print(self.price * self.quantity) def create_item(): global items_created num = int(input("number of items being added: ")) for _ in range(num): while True: name, price_str, quantity_str = input("name, price, quantity: ").split() price = float(price_str) quantity = int(quantity_str) assert price >= 0 assert quantity >= 0 # 每创建一个对象,编号递增一次,保证唯一性 items_created += 1 item_key = f"it{items_created}" # 直接创建对象并存入字典 items_store[item_key] = Item(name, price, quantity) unique = input("Y/N: ").strip().upper() if unique == "Y": unique_attr = input("unique attribute: ").strip() # 用setattr直接给对象添加属性,替代exec setattr(items_store[item_key], f"has_{unique_attr}", True) break create_item() # 从字典中取出it1实例打印 print(items_store["it1"])
关键修改说明
- 字典存储替代全局变量:
items_store字典可以统一管理所有Item对象,通过it1这类键就能快速找到对应实例,避免命名冲突。 - 修正编号计数逻辑:把
items_created的递增操作移到循环内部,每个对象都能获得唯一编号,不会被后续创建的实例覆盖。 - 移除exec:直接用
setattr给对象添加属性,比exec更安全直观;创建对象时直接赋值给字典键,完全避开动态执行代码的风险。 - 输入处理优化:提前转换输入的价格和数量类型,代码逻辑更清晰,也避免了重复转换的冗余操作。
内容的提问来源于stack exchange,提问作者Silver_9878
相关产品推荐
相关产品推荐

