我目前正在学习OOP,并且遇到了Dunder方法和继承的问题。
我有两个父类(都有自己的初始化),它们继承到一个子类,我想要一个在所有类中初始化的数据的字符串表示。
这就是问题:
#Parent class 1:
class Contact:
all_contacts = []
def __init__(self,name='',email='',**kwargs):
self.name = name
self.email = email
Contact.all_contacts.append(self)
def __str__(self):
return f'the name is {self.name}, and the mail is {self.mail}.'
#Parent class 2:
class AddressHolder:
def __init__(self, street='', city='', state='', code='', **kwargs):
self.street = street
self.city = city
self.state = state
self.code = code
def __str__(self):
return f'the street is {self.street}, the city is {self.city},
the state is {self.state}, the code is {self.code}'
#Subclass that inherits from both parent classes:
class Friends(Contact, AddressHolder):
def __init__(self, phone='', **kwargs):
self.phone = phone
super().__init__(**kwargs)
def __str__(self):
return f'''The phone is {self.phone}.'''
#The instance of the class
f = Friends(phone='aphone', name='aname', mail='amail',
street='astreet', city='acity', state='astate', code='acode')
print(f)这将仅打印电话初始化。
我试过这样做,这样所有的__str__都会被打印出来,但没有成功:
def __str__(self):
super(Contact.self).__str__()
super(AddressHolder.self).__str__()
return f'''The phone is {self.phone}.'''最初,我尝试将所有内容都放到Friends子类中,因为它是继承的,它应该可以工作:
def __str__(self):
return f'''The phone is {self.phone},
the street is {self.street},
the city is {self.city},
the state is {self.state},
the code is {self.code},
the name is {self.name},
and the mail is {self.mail}.'''但是我得到了一个街道错误:‘’对象没有属性‘AttributeError’‘错误(这不是我可以在子类上使用父类数据的继承点吗?)
我为每个类都提供了自己的__str__,这可以说是糟糕的代码,但也不起作用。
如何打印继承类加上子类的所有数据?
如果我得到一个“子类没有属性”的错误,继承的限制是什么?
发布于 2020-01-20 05:02:16
你需要让你的基类协同工作,让它们都调用super().__init__():
class Contact:
all_contacts = []
def __init__(self, name='', email='', **kwargs):
super().__init__(**kwargs)
self.name = name
self.email = email
Contact.all_contacts.append(self)和
class AddressHolder:
def __init__(self, street='', city='', state='', code='', **kwargs):
super().__init__(**kwargs)
self.street = street
self.city = city
self.state = state
self.code = code
def __str__(self):
return f'the street is {self.street}, the city is {self.city},
the state is {self.state}, the code is {self.code}'这之所以有效,是因为super()从当前类(定义方法的类)开始,在type(self)方法解析顺序的基类中搜索命名属性(此处为__init__)。对于Friends实例,MRO为:
>>> Friends.__mro__
(<class '__main__.Friends'>, <class '__main__.Contact'>, <class '__main__.AddressHolder'>, <class 'object'>)您已经使用关键字参数来传递额外的参数,因此在MRO的末尾将得到一个空的kwargs字典,有效地调用不带参数的object.__init__()。
请注意,您还可以在__str__方法中使用super():
class Contact:
# ...
def __str__(self):
return "\n".join([
f'the name is {self.name}, and the mail is {self.mail}.',
super().__str__()
])
class AddressHolder:
# ...
def __str__(self):
return "\n".join([
f'the street is {self.street}, the city is {self.city}, '
f'the state is {self.state}, the code is {self.code}',
super().__str__()
])
class Friends(Contact, AddressHolder):
# ...
def __str__(self):
return "\n".join([
f'The phone is {self.phone}.',
super().__str__()这适用于object定义的任何属性:
>>> print(*dir(object()), sep="\n")
__class__
__delattr__
__dir__
__doc__
__eq__
__format__
__ge__
__getattribute__
__gt__
__hash__
__init__
__init_subclass__
__le__
__lt__
__ne__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__sizeof__
__str__
__subclasshook__发布于 2020-01-20 06:50:40
您可以尝试这样做:
class A:
def __init__(self, a):
self.a = a
def __str__(self):
return self.a
class B:
def __init__(self, b):
self.b = b
def __str__(self):
return self.b
class C(A, B):
def __init__(self, a, b, c):
A.__init__(self, a)
B.__init__(self, b)
self.c = c
def __str__(self):
return A.__str__(self) + B.__str__(self) + self.c
c = C("a", "b", "c")
print(c)这将打印出abc。只需将a、b和c替换为所需的值即可。
https://stackoverflow.com/questions/59814330
复制相似问题