Python类中全局变量prodIDCounter无法更新导致Product ID重复问题
问题分析与解决方案
核心问题原因
- 类属性初始化时机错误:
Product类中的prodID = setProdID()是在类定义阶段执行的,仅运行一次,所有实例共享同一个初始值,不会在创建新实例时重新计算ID。 - 方法定义不符合Python规范:
setProdID()没有传入self参数,无法作为实例方法调用;且使用全局变量维护计数器不够优雅,更适合用类属性来管理。 - 子类未继承父类初始化逻辑:
Audio类的__init__没有调用父类Product的__init__,导致父类的初始化流程缺失,同时重复赋值prodName和price造成冗余。 - Cart类的共享属性问题:
purchasedItems是类属性,所有Cart实例会共用同一个列表,应该改为实例属性。
修正后的代码
class NameType: def __init__(self, nameUse): self.nameUse = nameUse class Product: # 用类属性维护计数器,替代全局变量 prodIDCounter = 0 def __init__(self, prodName, price): self.prodName = prodName self.price = price # 在实例初始化时生成唯一ID self.prodID = self.setProdID() self.review = "" def setProdName(self, newProdName): self.prodName = newProdName def setReview(self, review): self.review = review def setPrice(self, price): self.price = price def setProdID(self): Product.prodIDCounter += 1 return Product.prodIDCounter class Audio(Product): def __init__(self, prodName, price, name_type): # 调用父类初始化方法,继承父类逻辑 super().__init__(prodName, price) self.singer = name_type.nameUse self.genre = "" def setGenre(self, genre): self.genre = genre def printInfo(self): print("[Music]") print(f"Product ID: {self.prodID} Product Name: {self.prodName}") print(f"Price: ${self.price} Product Review Rate: {self.review}") print(f"Singer Name: {self.singer}") print(f"Genre: {self.genre}\n") class Cart: MAX_ITEMS = 7 def __init__(self, name_type): self.owner = name_type.nameUse # 改为实例属性,每个Cart实例有独立的购物车列表 self.purchasedItems = [] def addItem(self, product): if len(self.purchasedItems) < Cart.MAX_ITEMS: self.purchasedItems.append(product.prodID) def removeItem(self, prodIDRemove): if prodIDRemove in self.purchasedItems: self.purchasedItems.remove(prodIDRemove) def displayCart(self): print(f"Cart Owner: {self.owner}") print(f"Purchased Items IDs: {self.purchasedItems}") # 测试代码 name1 = NameType("Bailey") myCart = Cart(name1) print(myCart.owner) name1 = NameType("Music Artst") music1 = Audio("Song Name", 5.50, name1) music1.setReview(8.2) music1.setGenre("Pop") music1.printInfo() name1 = NameType("Music Artist 2") music2 = Audio("Song Name 2", 6, name1) music2.setReview(7) music2.setGenre("Punk") music2.printInfo() myCart.addItem(music1) myCart.addItem(music2) print(myCart.purchasedItems)
关键修改说明
- 将全局变量
prodIDCounter改为Product类的类属性,避免全局变量污染,同时方便子类共享计数器。 - 在
Product的__init__方法中调用setProdID()生成实例的prodID,确保每个实例创建时都会触发ID自增。 Audio类通过super().__init__()调用父类初始化方法,继承父类的属性和逻辑,减少冗余代码。- 将
Cart类的purchasedItems改为实例属性,在__init__中初始化,保证每个购物车实例有独立的商品列表。 - 优化了
printInfo中的字符串拼接,使用f-string更简洁易读。
运行结果
Bailey [Music] Product ID: 1 Product Name: Song Name Price: $5.5 Product Review Rate: 8.2 Singer Name: Music Artst Genre: Pop [Music] Product ID: 2 Product Name: Song Name 2 Price: $6 Product Review Rate: 7 Singer Name: Music Artist 2 Genre: Punk [1, 2]
内容的提问来源于stack exchange,提问作者Bailey
相关产品推荐
相关产品推荐

