我正在尝试扩展Python库以添加我想要的功能。该库提供了许多HTML表单对象(例如Textbox
,Dropdown
,Checkbox
等),所有这些都来自Input
对象。我想为所有这些派生对象添加一个附加属性。什么是正确的处理方式?
我可以:
Input
类的原始源代码,添加我想要的属性。Input
并添加我的属性的新类,然后创建一堆继承Textbox
,Dropdown
和我的新Input
类的新类Textbox
,Dropdown
等创建新类。解决方案1是最简单和最简单的,但本质上是错误的,而其他两个似乎比这个任务应该要求的工作和代码重复更多。
我缺少一个解决方案吗?
答案 0 :(得分:4)
第四个解决方案是猴子修补,可能是个好主意。在您尝试此操作之前,请确保现在或将来不会破坏任何内容:
def additional_method(self, arg):
print("hello", arg)
Input.additional_method = additional_method
或简称:
Input.additional_method = lambda self, arg: do_something(arg)
现在所有现有和未来Input
个实例(以及所有Input
子类的实例)都附加了additional_method
。
这也适用于Input
的任何未来子类,这些子类在添加方法时可能还不存在,或者您可能不知道,因此比创建更好(即更通用)另一种继承层次结构,您必须维护该层次结构并与上游更改保持同步。
注意:之前,因为它包含短语“猴子修补”而你的downvote,考虑猴子修补不必是危险/脆弱,并且是第一类(如“尊重” “)多种语言的功能。
答案 1 :(得分:3)
您可以使用mixin(多重继承)。它是一个只包含额外属性的类,并将此类添加到Textbox, Dropdown, Checkbox...
的子类的父类中,如下所示:
from ... import TextBox
class Mixin:
def __init__(self):
self.new_attribude = ...
class TextBox_with_new_attribute(Mixin, TextBox):
pass
但是,这完全取决于你的目标......
编辑:基于@Veedrac评论,如果是第三方库。
答案 2 :(得分:1)
如果有很多课程,你可以动态应用mixin:
for cls in list_of_classes_to_patch:
patched = type(cls.__name__, (my_mixin, cls), {})
setattr(place_to_export, cls.__name__, patched)
place_to_export
可以定义为import this_module as place_to_export
。