python中的动态父类

时间:2018-03-05 17:15:12

标签: python inheritance widget

django-file-resubmit模块(文件widgets.py)进行导入:

from django.forms import ClearableFileInput

然后它根据ClearableFileInput:

定义类
class ResubmitBaseWidget(ClearableFileInput):
    # ...some code

我尝试使用具有不同基类的模块,它运行良好。但我必须在模块代码中修补import命令。 (DBAdminClearableFileInput继承自其他第三方模块中的django.forms.ClearableFileInput):

from db_file_storage.form_widgets import DBAdminClearableFileInput as ClearableFileInput

我的问题是:django-file-resubmit模块的代码是否可以更加巧妙地重写,因此它可以与DBAdminClearableFileInput一起用作参数?

注意:我不确定这不是重复的问题。但是我认为这里是模块设计的特殊问题,如果可以提出一些Pull Request,或者如何在不改变它们的情况下使用这两个模块的最佳方法是什么。

1 个答案:

答案 0 :(得分:1)

听起来你真正想要的是合作多重继承。例如。你想拥有

class MyFileInput(DBAdminClearableFileInput, ResubmitBaseWidget):
    pass

为了实现这一目标,DBAdminClearableFileInputResubmitBaseWidget都需要考虑合作多重继承。根据最终状态行为的外观,它甚至可能(理论上)不可能。例如。如果DBAdminClearableFileInput想要将小部件呈现为<foo>并且ResubmitBaseWidget想要将小部件呈现为<bar>,则其中一个必须赢得&#39; (如果没有其他代码,您可以在MyFileInput中自行编写。

可能(尽管可能不太可能)多重继承只会工作,这取决于这些类重写的方法等,以及它们是否使得它们已经对{{{}进行了正确的调用1}}。

至少可能值得一试,在最糟糕的情况下,你可以添加一些胶水&#39;到你的super()课程,让它发挥作用。

这是一个陈腐的例子

MyFileInput

现在,目前,这些类不合作,所以如果你做多重继承,你会得到:

class Elephant:  # Represents ClearableFileInput
    def colour(self):
        return "Grey"

class BrownElephant(Elephant):  # Represents ResubmitBaseWidget
    def colour(self):
        return "Brown"

class PinkElephant(Elephant):  # Represents DBAdminClearableFileInput
    def colour(self):
        return "Pink"

将打印&#34; Brown&#34;,因为方法解析顺序以class BrownAndPinkElephant(BrownElephant, PinkElephant): pass nelly = BrownAndPinkElephant() print(nelly.colour()) 开头,它返回&#34; Brown&#34;没有打电话给BrownElephant,所以Pink和&#39;默认&#39;大象的方法甚至从未被召唤过。

你可以修复&#39;这是一个非常有限的(但可能足够你的目的)与一个hacky&#39;胶水&#39;像这样的方法:

super().colour()

现在打印的输出是&#34; Brown和Pink&#34;,这是更明智的(至少在这个例子的上下文中!)。希望你可以看到你试图为class BrownAndPinkElephant(BrownElephant, PinkElephant): def colour(self): colours = [ BrownElephant.colour(self), PinkElephant.colour(self), ] return " and ".join(colours) nelly = BrownAndPinkElephant() print(nelly.colour()) DBAdminClearableFileInput的子类实现类似的东西,让你可以控制最终类中最终使用的每个类的哪些方面。

值得一提的是,这种方法存在很多陷阱,我不会推荐它用于任何严肃的事情。但是,当你有2个具有公共基类的类,你想要组合,并且你不能控制任何一个的源代码时,那么这可能是一个可能的解决方案。