簡體   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