python中的动态父类

2024-05-23 17:52:10 发布

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

django文件重新提交模块(文件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文件重新提交模块的代码是否可以重写得更巧妙一些,这样就可以用DBAdminClearableFileInput作为参数

注意:我不确定这是否是一个重复的问题。然而,我认为这里有一些特殊的模块设计问题和一个问题,如果一些拉请求可以作出或什么是最好的办法,如何使用这两个模块而不改变他们


Tags: 模块文件django代码frompyimport定义
1条回答
网友
1楼 · 发布于 2024-05-23 17:52:10

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

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(),因此Pink和'default'Elephant的方法甚至从未被调用

你可以用一个非常简单的“胶水”方法来“修复”这个问题(但对于你的目的来说可能已经足够了):

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

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

现在打印的输出是“Brown and Pink”,这更合理(至少在本例的上下文中是这样!)。希望您可以看到,您尝试为DBAdminClearableFileInput的子类实现类似的功能,ResubmitBaseWidget使您能够控制每个类的哪些方面最终会在最后一个类中使用

值得一提的是,这种方法有很多缺陷,我不推荐任何“严重”的情况。但是,如果您有两个具有公共基类的类,您想合并它们,并且您不控制它们的源代码,那么这可能是一个可行的解决方案

相关问题 更多 >