【问题标题】:How to define a method so that return the instance of the current class not of the class where it was inherited in Python?如何定义一个方法,以便返回当前类的实例而不是它在 Python 中继承的类的实例?
【发布时间】:2016-06-03 01:14:55
【问题描述】:

我正在尝试重载一个运算符,强制它返回当前类的同一实例的对象,而不是方法被重载的父类。

class Book:
    def __init__(self,name,pages):
        self.name=name
        self.pages=pages

    def __add__(self,other):
        return Book(self.name,(self.pages + other.pages))


class Encyclopedia(Book):
    def __init__(self,name,pages):
        Book.__init__(self,name,pages)


a=Encyclopedia('Omina',234)
b=Encyclopedia('Omnia2',244)
ab=a+b
print ab

Out: <__main__.Book instance at 0x1046dfd88>

例如,在这种情况下,我想返回一个Encycolpedia 实例(不是Book 实例),而不会再次重载运算符__add__Encyclopedia 的同一行而不是Book 我有试过了:

return self(self.name,(self.pages + other.pages))

但它不起作用。

如果类百科全书有另一个属性怎么办:

class Encyclopedia(Book):
    def __init__(self,name,pages,color):
        Book.__init__(self,name,pages)
        self.color=color

【问题讨论】:

    标签: python class inheritance operator-overloading


    【解决方案1】:

    您可以使用 self.__class__ 而不是强制转换为 Book。您的原始添加函数应如下所示:

    def __add__(self,other):
        return self.__class__(self.name,(self.pages + other.pages))
    

    【讨论】:

    • 如果类百科全书有另一个属性呢?
    • @GM 然后你需要重写 Encyclopedia 类中的加法运算符来处理该属性。
    【解决方案2】:

    你需要做这样的事情,它会重载基类的方法(在这种情况下,通常是先调用它们,然后对结果进行额外的处理——尽管这不是必需的):

    class Book(object):
        def __init__(self, name, pages):
            self.name = name
            self.pages = pages
    
        def __add__(self, other):
            return Book(self.name, self.pages+other.pages)
    
        def __str__(self):
            classname = self.__class__.__name__
            return '{}({}, {})'.format(classname, self.name, self.pages)
    
    class Encyclopedia(Book):
        def __init__(self, name, pages, color):
            Book.__init__(self, name, pages)
            self.color = color
    
        def __add__(self, other):
            tmp = super(Encyclopedia, self).__add__(other)
            return Encyclopedia(tmp.name, tmp.pages, self.color+other.color)
    
        def __str__(self):
            classname = self.__class__.__name__
            return '{}({!r}, {}, {!r})'.format(classname, self.name, self.pages,
                                             self.color)
    
    
    a = Encyclopedia('Omina', 234, 'grey')
    b = Encyclopedia('Omnia2', 244, 'blue')
    ab = a+b
    print(ab)  # -> Encyclopedia('Omina', 478, 'greyblue')
    

    【讨论】:

    • 谢谢martineu,但是这样你在操作符 add 的时候又超载了,我正在寻找一个不重复代码的解决方案
    • 代码确实重复__add__()方法的基类中的代码,它使用它......然后做任何事情需要额外的处理来处理仅由派生类拥有的属性。这是必要的,因为基类不知道从它派生的子类——因此是进行面向对象编程的规范方法。
    猜你喜欢
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多