如何在类变量中记录实例属性,同时让父类汇总所有子类实例数据?
问题
我是Python新手,目前遇到类继承相关问题。我定义了Food父类,以及Burger、Desserts等子类,希望实现:
- 每个子类的prices类变量仅存储该子类实例的product(名称)和price(价格);
- 父类Food的prices类变量存储所有子类实例的product和price。
但当前实现中,所有类(父类和子类)的prices字典都包含了所有子类的实例数据,这与预期不符。以下是我的代码及输出:
class Food: prices = {} def __init__(self, product, price): self.product = product self.price = price self.prices[self.product] = [self.price] class Burger(Food): pass class Desserts(Food): pass #--->burger menu burger_option_1 = Burger("burger option 1", 15) burger_option_2 = Burger("burger option 2", 20) burger_option_3 = Burger("burger option 3", 25) #--->dessert menu dessert_option_1 = Desserts("dessert option 1", 15) dessert_option_2 = Desserts("dessert option 2", 20) dessert_option_3 = Desserts("dessert option 3", 25) print(f"Food.prices: {Food.prices}") print(f"Burger.prices: {Burger.prices}") print(f"Desserts.prices: {Desserts.prices}")
输出:
Food.prices: {'burger option 1': [15], 'burger option 2': [20], 'burger option 3': [25], 'dessert option 1': [15], 'dessert option 2': [20], 'dessert option 3': [25]} Burger.prices: {'burger option 1': [15], 'burger option 2': [20], 'burger option 3': [25], 'dessert option 1': [15], 'dessert option 2': [20], 'dessert option 3': [25]} Desserts.prices: {'burger option 1': [15], 'burger option 2': [20], 'burger option 3': [25], 'dessert option 1': [15], 'dessert option 2': [20], 'dessert option 3': [25]}
解决方案
问题根源在于Python中子类会共享父类的可变类变量(比如这里的字典),除非子类自己重新定义该变量。要实现需求,需要做以下调整:
- 给每个子类单独定义
prices字典,避免和父类共享; - 在父类的
__init__方法中,同时将实例数据添加到父类的prices和当前子类的prices中。
修改后的代码如下:
class Food: prices = {} def __init__(self, product, price): self.product = product self.price = price # 添加到当前类的prices(子类自己的字典) self.__class__.prices[self.product] = [self.price] # 添加到父类Food的prices Food.prices[self.product] = [self.price] class Burger(Food): # 子类单独定义prices字典,不共享父类的 prices = {} class Desserts(Food): prices = {} #--->burger menu burger_option_1 = Burger("burger option 1", 15) burger_option_2 = Burger("burger option 2", 20) burger_option_3 = Burger("burger option 3", 25) #--->dessert menu dessert_option_1 = Desserts("dessert option 1", 15) dessert_option_2 = Desserts("dessert option 2", 20) dessert_option_3 = Desserts("dessert option 3", 25) print(f"Food.prices: {Food.prices}") print(f"Burger.prices: {Burger.prices}") print(f"Desserts.prices: {Desserts.prices}")
运行后输出:
Food.prices: {'burger option 1': [15], 'burger option 2': [20], 'burger option 3': [25], 'dessert option 1': [15], 'dessert option 2': [20], 'dessert option 3': [25]} Burger.prices: {'burger option 1': [15], 'burger option 2': [20], 'burger option 3': [25]} Desserts.prices: {'dessert option 1': [15], 'dessert option 2': [20], 'dessert option 3': [25]}
关键说明
self.__class__会返回当前实例所属的类(比如Burger实例返回Burger类),这样就能确保数据添加到子类自己的prices字典中;- 每个子类必须显式定义
prices = {},否则会继续沿用父类的字典,导致数据共享; - 父类的
Food.prices直接被赋值,确保所有子类的实例数据都能汇总到这里。
内容的提问来源于stack exchange,提问作者smithycey
相关产品推荐
相关产品推荐

