1

我正在尝试扩展 Python 库以添加我想要的功能。该库提供了许多 HTML 表单对象(例如TextboxDropdownCheckbox等),它们都派生自一个Input对象。我想为所有这些派生对象添加一个附加属性。正确的处理方式是什么?

我可以:

  1. 修改Input类的原始源代码,添加我想要的属性。
  2. 创建一个继承Input并添加我的属性的新类,然后创建一堆继承的新类TextboxDropdown和我的新Input类。
  3. Textbox使用该属性为、Dropdown等创建新类。

解决方案 1 是最简单和最简单的,但本质上是错误的,而其他两个似乎比这项任务需要更多的工作和代码重复。

有我缺少的解决方案吗?

4

3 回答 3

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可能还不存在的子类,或者您在添加方法时可能不知道,因此比创建替代继承层次结构更好(即更通用),你'然后必须维护并与上游更改保持同步。

注意:在仅仅因为它包含短语“猴子补丁”而投反对票之前,请考虑猴子补丁不一定是危险/脆弱的,并且是许多语言中的一流(如“受尊重”)功能。

于 2013-09-27T22:34:27.907 回答
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 评论,如果是第三方库。

于 2013-09-27T22:34:51.933 回答
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

于 2013-09-27T22:44:55.363 回答