Python多层继承报错:'CheckingAccount'对象无'balance'属性
解决多层继承中
'CheckingAccount' object has no attribute 'balance'的问题 嘿,我看到你在多层继承的Python项目里遇到了属性找不到的问题,咱们来一步步拆解问题出在哪:
核心问题分析
你遇到的AttributeError本质是子类CheckingAccount和SavingAccount没有正确初始化父类BankAccount的属性。你的子类构造函数里只是把传入的对象存在self.bankAccount里,完全没有调用父类的__init__方法,导致balance、accountNumber这些父类属性根本没被创建,自然访问不到。
另外还有两个隐藏问题:
BankAccount里的accountNumber是类属性,在类定义时就生成了,这意味着所有BankAccount实例都会共用同一个账号,这显然不符合实际需求。BankAccount的__init__接收customer参数,但你的子类在实例化时直接传了Customer对象,却没正确对接父类的构造逻辑。
修正后的代码
下面是修复好的完整代码,我会标注关键修改点:
from random import randint # 把导入放到文件顶部,避免重复导入 class Customer: def __init__(self, firstName, lastName, social): self.firstName = firstName self.lastName = lastName self.social = social def setfirstName(self, firstName): self.firstName = firstName def setlastName(self, lastName): self.lastName = lastName def __str__(self): # 不要在__str__里修改实例属性self.name,直接返回字符串即可 return "{}, {} (SSN:{})".format(self.firstName, self.lastName, self.social) class BankAccount(Customer): def __init__(self, customer, balance=0): # 调用父类Customer的构造函数,初始化Customer的属性 super().__init__(customer.firstName, customer.lastName, customer.social) # 把accountNumber改成实例属性,每个账号生成唯一值 n = 10 range_start = 10 ** (n - 1) range_end = (10 ** n) - 1 self.accountNumber = randint(range_start, range_end) self.balance = balance def setCustomer(self, customer): self.firstName = customer.firstName self.lastName = customer.lastName self.social = customer.social def getCustomer(self): # 不需要传参数,直接返回实例自身的Customer属性 return (self.firstName, self.lastName, self.social) def deposit(self, amount): self.balance += amount return self.balance def withdrawal(self, amount): self.balance -= amount return self.balance def __str__(self): return "{} account number: {}, balance: ${:.2f}".format( super().__str__(), self.accountNumber, self.balance ) class CheckingAccount(BankAccount): def __init__(self, customer, balance=0): # 调用父类BankAccount的构造函数,初始化balance等属性 super().__init__(customer, balance) def applyAnnualInterest(self): excess = self.balance - 10000 if excess > 0: self.balance += excess * 0.02 return self.balance class SavingAccount(BankAccount): def __init__(self, customer, balance=0): # 同样调用父类构造函数 super().__init__(customer, balance) def applyAnnualInterest(self): self.balance += self.balance * 0.05 return self.balance def main(): alin = Customer('Alin', 'Smith', '111-11-1111') mary = Customer('Mary', 'Lee', '222-22-2222') # 实例化子类时,直接传Customer对象和初始余额(可选) alinAccnt = CheckingAccount(alin, 0) maryAccnt = SavingAccount(mary, 0) alinAccnt.deposit(20000) alinAccnt.applyAnnualInterest() # 可以测试利息计算 print(alinAccnt) if __name__ == "__main__": main()
关键修改说明
- 修复子类构造函数:
- 用
super().__init__(...)调用父类的构造函数,让子类继承父类的所有属性(比如balance、accountNumber),而不是把父类对象存成一个属性。
- 用
- 修正
accountNumber为实例属性:- 把账号生成逻辑放到
BankAccount的__init__里,确保每个银行账号实例都有唯一的账号。
- 把账号生成逻辑放到
- 优化
Customer的__str__方法:- 不要在
__str__中修改实例属性,直接返回格式化后的字符串即可,避免不必要的副作用。
- 不要在
- 调整
BankAccount的setCustomer和getCustomer方法:- 因为
BankAccount继承自Customer,所以直接操作自身的firstName等属性即可,不需要额外存self.customer对象。
- 因为
现在运行代码,你会发现balance属性能正常访问,存款、利息计算也都能正常工作了!
内容的提问来源于stack exchange,提问作者Kris
相关产品推荐
相关产品推荐

