首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >继承和dunder方法?

继承和dunder方法?
EN

Stack Overflow用户
提问于 2020-01-20 04:57:49
回答 2查看 417关注 0票数 0

我目前正在学习OOP,并且遇到了Dunder方法和继承的问题。

我有两个父类(都有自己的初始化),它们继承到一个子类,我想要一个在所有类中初始化的数据的字符串表示。

这就是问题:

代码语言:javascript
复制
#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__都会被打印出来,但没有成功:

代码语言:javascript
复制
    def __str__(self):
        super(Contact.self).__str__()
        super(AddressHolder.self).__str__()
        return f'''The phone is {self.phone}.'''

最初,我尝试将所有内容都放到Friends子类中,因为它是继承的,它应该可以工作:

代码语言:javascript
复制
    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__,这可以说是糟糕的代码,但也不起作用。

如何打印继承类加上子类的所有数据?

如果我得到一个“子类没有属性”的错误,继承的限制是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-20 05:02:16

你需要让你的基类协同工作,让它们都调用super().__init__()

代码语言:javascript
复制
class Contact:

    all_contacts = []

    def __init__(self, name='', email='', **kwargs):
        super().__init__(**kwargs)
        self.name = name
        self.email = email
        Contact.all_contacts.append(self)

代码语言:javascript
复制
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为:

代码语言:javascript
复制
>>> Friends.__mro__
(<class '__main__.Friends'>, <class '__main__.Contact'>, <class '__main__.AddressHolder'>, <class 'object'>)

您已经使用关键字参数来传递额外的参数,因此在MRO的末尾将得到一个空的kwargs字典,有效地调用不带参数的object.__init__()

请注意,您还可以在__str__方法中使用super()

代码语言:javascript
复制
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定义的任何属性:

代码语言:javascript
复制
>>> 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__
票数 2
EN

Stack Overflow用户

发布于 2020-01-20 06:50:40

您可以尝试这样做:

代码语言:javascript
复制
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替换为所需的值即可。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59814330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档