2012-05-26 52 views
1

這個問題是關於Python繼承,但用Django的例子解釋,但這應該不會受傷。使用從其他類沒有繼承的方法

我有這樣的Django模型,用PageRichText模型,以及:

class Gallery(Page, RichText): 
    def save(self, *args, **kwargs): 
     # lot of code to unzip, check and create image instances. 
     return "something" 

我只是在另一個類使用save方法感興趣。

一個解決辦法是:

class MyGallery(models.Model): 
    def save(self, *args, **kwargs): 
     # here goes the code duplicated from Gallery, the same. 
     return "something" 

我想,以避免重複代碼,也我不感興趣,從PageRichText繼承成員(所以我不想做class MyGallery(Gallery):。如果是合法我會寫這樣的事:

class MyGallery(models.Model): 
    # custom fields specific for MyGallery 
    # name = models.CharField(max_length=50) 
    # etc 

    def save(self, *args, **kwargs): 
     return Gallery.save(self, *args, **kwargs) 

但它不會起作用,因爲Gallerysave()預計Gallery一個實例,而不是MyGallery

任何方式從Gallery「分離」save()方法,並在MyGallery中使用它,因爲它是在那裏定義的?

編輯:

我忘了說,Gallery,並給出不能改變。

回答

2

您可以訪問__func__ attribute of the save method

class Gallery(object): 
    def save(self, *args, **kwargs): 
     return self, args, kwargs 

class MyGallery(object): 
    def save(self, *args, **kwargs): 
     return Gallery.save.__func__(self, *args, **kwargs) 
    # or 
    # save = Gallery.save.__func__ 

mg = MyGallery() 
print mg.save('arg', kwarg='kwarg') 
# (<__main__.MyGallery object at 0x04DAD070>, ('arg',), {'kwarg': 'kwarg'}) 

,但你最好還是重構如果可能的話:

class SaveMixin(object): 
    def save(self, *args, **kwargs): 
     return self, args, kwargs 

class Gallery(SaveMixin, object): 
    pass 

class MyGallery(SaveMixin, object): 
    pass 

def gallery_save(self, *args, **kwargs): 
    return self, args, kwargs 

class Gallery(object): 
    save = gallery_save 

class MyGallery(object): 
    save = gallery_save 
0

我不知道你爲什麼反對繼承,特別是在方法方面。我經常創建一個由我的所有Django models.Model繼承的類,它包含所有方式的URL創建,轉儲等等的有用方法。我確實使這些方法具有防禦性,因爲它們使用hasattr()來確保它們適用於特定的班級,但這樣做是實時的節省。

+0

我不反對一般的繼承,但在這種情況下,我是。如果'MyGallery'繼承自'Gallery',那麼子類將擁有我永遠不會使用的方法,所以對於我來說,擁有一些你不需要但是需要內存的東西似乎是無稽之談。然後,就Django的工作原理而言,繼承的類也會對新的數據庫字段(在我的方案中無用)作出貢獻。 – Paolo

+0

最後,mixins不適合,因爲我無法更改'Gallery'類。 – Paolo

+1

@Guandalino:我承認這不是你想要做到的,但我不相信從其他類繼承的Python方法比從子類到父類的簡單指針佔用更多空間。至於數據庫領域,我完全同意你的意見。我試過這樣做了幾次,這是一個尷尬,b)不直觀。祝你好運。 –