python中的动态父类

问题描述 投票:0回答:1

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,或者如何在不改变它们的情况下使用这两个模块的最佳方法是什么。

python inheritance widget
1个回答
1
投票

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

class MyFileInput(DBAdminClearableFileInput, ResubmitBaseWidget):
    pass

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

有可能(尽管可能不太可能)多重继承将“正常工作”,这取决于这些类重写的方法等,以及它们是否使得它们已经对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"

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

class BrownAndPinkElephant(BrownElephant, PinkElephant):
    pass

nelly = BrownAndPinkElephant()
print(nelly.colour())

将打印“Brown”,因为方法解析顺序以BrownElephant开头,它返回“Brown”而没有调用super().colour(),因此粉红色和'默认'大象的方法甚至从未调用过。

您可以使用像这样的hacky' glue'方法在一个非常有限的(但可能足以满足您的目的)'修复'这个:

class BrownAndPinkElephant(BrownElephant, PinkElephant):
    def colour(self):
        colours = [
            BrownElephant.colour(self),
            PinkElephant.colour(self),
        ]
        return " and ".join(colours)

nelly = BrownAndPinkElephant()
print(nelly.colour())

现在印刷的输出是“棕色和粉红色”,这是更明智的(至少在这个例子的上下文中!)。希望您可以看到您尝试为DBAdminClearableFileInputResubmitBaseWidget的子类实现类似的东西,以便控制每个类的哪些方面最终在最终类中使用。

值得一提的是,这种方法存在很多陷阱,我不建议任何“严肃”的东西。但是,如果您有两个具有公共基类的类,您想要组合,并且您不控制任何一个的源代码,那么这可能是一个可能的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.