将属性添加到Python库中的基类并将其继承的正确方法是什么?

时间:2013-09-27 22:19:48

标签: python inheritance

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

我可以:

  1. 修改Input类的原始源代码,添加我想要的属性。
  2. 创建一个继承Input并添加我的属性的新类,然后创建一堆继承TextboxDropdown和我的新Input类的新类
  3. 使用属性为TextboxDropdown等创建新类。
  4. 解决方案1是最简单和最简单的,但本质上是错误的,而其他两个似乎比这个任务应该要求的工作和代码重复更多。

    我缺少一个解决方案吗?

3 个答案:

答案 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