Python父子类继承:子类如何继承父类属性并解决属性缺失报错
现有定义用户档案的Profile父类,包含account_holder、account_type、value属性及info方法。创建继承自Profile的Business子类时重写了__init__方法,添加自身属性与方法,但调用子类实例的info方法时出现AttributeError,提示不存在account_holder属性。请问如何在创建子类实例时传入父类的account_holder、account_type、value属性?或者是否应为这些属性设置默认值?
父类代码
class Profile: # this is the class constructor def __init__(self, account_holder, account_type, value): self.account_holder = account_holder self.account_type = account_type self.value = value # some methods for the user account: def info(self): print(self.account_holder) print(self.account_type) print(self.value) # create object: personal_acc = Profile(account_holder='Me', account_type='main account', value= 100) personal_acc.info()
子类代码
class Business(Profile): # this is a child class: def __init__(self, business_name, business_value = 100): self.business_name = business_name self.business_value = business_value # new_method def increase_value(self, increase = 400): self.business_value += increase meta = Business(business_name='whatsapp', business_value = 1000) meta.increase_value() print(meta.business_value) # print a method of the parent class using child class Business: meta.info()
报错信息
Traceback (most recent call last):
File "c:\Users\beans\test.py", line 558, in
meta.info()
File "c:\Users\beans\test.py", line 523, in info
print(self.account_holder)
AttributeError: 'Business' object has no attribute 'account_holder'
错误原因
重写子类__init__方法时,没有调用父类的__init__构造方法,导致父类定义的account_holder、account_type、value属性从未被初始化,调用父类info方法时自然找不到这些属性。
解决方案
方案1:显式调用父类构造方法,强制传入父类参数
修改子类__init__,先通过super()调用父类构造方法,完成父类属性的初始化,再处理子类自身属性:
class Business(Profile): def __init__(self, account_holder, account_type, value, business_name, business_value=100): # 调用父类构造方法,传入父类所需参数 super().__init__(account_holder, account_type, value) self.business_name = business_name self.business_value = business_value def increase_value(self, increase=400): self.business_value += increase # 创建实例时必须传入父类和子类的所有参数 meta = Business(account_holder='Meta Inc.', account_type='business account', value=50000, business_name='whatsapp', business_value=1000) meta.info() # 可正常输出父类属性
方案2:为父类参数设置默认值(可选)
如果业务允许父类属性有默认值,可以修改父类__init__的参数默认值,这样子类实例化时可灵活选择是否传入父类参数:
修改父类:
class Profile: def __init__(self, account_holder='Unknown', account_type='default', value=0): self.account_holder = account_holder self.account_type = account_type self.value = value def info(self): print(self.account_holder) print(self.account_type) print(self.value)
子类实现:
class Business(Profile): def __init__(self, business_name, business_value=100, account_holder='Unknown', account_type='business', value=0): super().__init__(account_holder, account_type, value) self.business_name = business_name self.business_value = business_value # 仅传入子类参数,使用父类默认属性值 meta = Business(business_name='whatsapp', business_value=1000) meta.info() # 输出:Unknown、business、0 # 也可以主动传入父类参数 meta2 = Business(account_holder='Meta Inc.', account_type='corporate', value=100000, business_name='facebook', business_value=5000) meta2.info() # 输出:Meta Inc.、corporate、100000
方案选择
- 若父类属性是业务必需项,优先用方案1,确保实例化时必须传入完整参数;
- 若父类属性允许缺省,用方案2可简化实例化流程。
内容的提问来源于stack exchange,提问作者Beans On Toast

