2016-02-21 32 views
4

我想重載一個操作符強制它返回當前類的同一個實例的對象,而不是方法被重載的父類。如何定義一個方法,以便返回當前類的實例而不是返回它在Python中繼承的類的實例?

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> 

例如,在這種情況下,我想沒有超載另一次操作__add__Encyclopedia代替Book同一行我試圖返回一個Encycolpedia實例(不是Book實例):

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

但它不起作用。

如果類Enclcopedia有另一個屬性:

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

回答

6

你可以利用自.__ class__而不是鑄造書。你的原始添加的功能應該是這樣的:

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

如果類百科全書具有另一個屬性,該怎麼辦? –

+0

@GM然後,您需要重寫Encyclopedia類中的添加運算符來處理該屬性。 –

+0

嗯我明白,所以在這個例子中繼承幾乎是無用的... –

1

您需要先調用它們,然後對結果做額外的處理做這樣的事情,這重載基類的方法(在這種情況下,一般 - 雖然這不是要求):

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') 
+0

感謝martineu,但以這種方式,你有過載運算符__add__和我正在尋找一個解決方案,而不重複代碼 –

+0

代碼沒有_not_重複代碼'__add __()'方法的基類,它會使用它...然後執行任何額外的處理來處理僅由派生類擁有的屬性。這是必要的,因爲基類不知道將從它派生的子類 - 因此是執行面向對象編程的規範方法。 – martineau

相關問題