使用其他类的方法,但不使用inheritan

2024-10-03 23:25:15 发布

您现在位置:Python中文网/ 问答频道 /正文

这个问题是关于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)

但是它不起作用,因为Gallery中的save()需要一个Gallery的实例,而不是MyGallery。你知道吗

有没有办法将save()方法从Gallery中“分离”出来,并在MyGallery中使用它?你知道吗

编辑:

我忘了说Gallery是给定的,不能更改。你知道吗


Tags: django模型selfreturnmodelssavedefpage
2条回答

您可以访问^{} attribute of the ^{} 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

我不知道你为什么反对继承,特别是在方法方面。我定期创建一个MixIn类,这个类由我所有的Django models.Model继承,它包含各种有用的URL创建、转储等方法。我确实让这些方法具有防御性,因为它们使用hasattr()来确保它们应用于某个特定的类,但是这样做可以节省大量的时间。你知道吗

相关问题 更多 >