这个问题是关于 Python 的继承,但用Django示例解释,但这不应该有害。
我有这个Django模型,还有Page
和RichText
模型:
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"
我想避免代码重复,而且我对继承Page
和RichText
的成员不感兴趣(所以我不想做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)
但它不起作用,因为save()
中的Gallery
需要Gallery
的实例,而不是MyGallery
。
是否可以从save()
“分离”Gallery
方法,并在MyGallery
中使用它,因为它在那里定义了?
修改
我忘了说Gallery
已经给出且无法更改。
答案 0 :(得分: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
答案 1 :(得分:0)
我不确定你为什么反对继承,特别是在方法方面。我经常创建一个由我的所有Django MixIn
继承的models.Model
类,它包含用于URL创建,转储等的所有有用方法。我确实使这些方法具有防御性他们使用hasattr()
来确保它们适用于特定的课程,但这样做可以节省时间。