繁体   English   中英

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

[英]What is the proper way to add an attribute to a base class in a Python library and have it inherited?

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

我可以:

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

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

有我找不到的解决方案吗?

第四个解决方案是修补猴子,这可能是个好主意。 在尝试此操作之前,请确保现在或将来不会破坏任何内容:

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_methodadditional_method

这对于添加方法时甚至可能还不存在或您可能不知道的Input任何将来子类也适用,因此,比创建替代继承层次结构更好(即更通用),您可以然后必须维护并与上游更改保持同步。

注意:在仅因为它包含短语“ monkey patching”而进行否决投票之前,请考虑一下猴子补丁不一定是危险/脆弱的,并且在许多语言中都是头等舱(如“尊敬的”)功能。

您可以使用混合(多重继承)。 这是一个只包含您额外属性的类,并将该类添加到Textbox, Dropdown, Checkbox...的子类的父类中Textbox, Dropdown, Checkbox...如下所示:

from ... import TextBox

class Mixin:
    def __init__(self):
        self.new_attribude = ...

class TextBox_with_new_attribute(Mixin, TextBox):
    pass

但是,这完全取决于您的目标...

编辑:在第三方库的情况下,基于@Veedrac注释。

如果有很多类,则可以动态应用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM