我想扩展一个处理 HTML 或 XML 结构的 Python (2.7) 类。目前我正在摆弄 bs4,但这对于这个问题可能并不重要。
我想添加一堆执行更高级别操作的函数;比如说,操作整个表格列,排序列表子元素等。所以我定义了一个子类
class myBS4 (bs4.BeautifulSoup):
def sortChildren(self, keyPath,...):
...
到目前为止还好。但是原始类(以及相关的,如 Tag、NavigableString 等)已经有各种实例化 bs4 对象的方法,例如 new_tag() 用于制作“Tag”(元素),new_string() 用于制作 NavigableString(文本节点) ) 等。与基于 DOM 的类或任何处理递归数据结构的包相同。
这是否意味着我必须在每个与 bs4 相关的类中找到实例化与 bs4 相关的对象的每个位置,以及子类和覆盖,以便它们都实例化我的类?这似乎非常乏味。
更糟糕的是,它似乎很容易出现细微的错误。例如,bs4 构造函数从解析的 HTML 或 XML 构造一个准 DOM 树;但这样做时它可能会或可能不会调用 new_tag() 。它可能只是说类似
x = Tag("div")
在这种情况下,我会将 BeautifulSoup 和 Tag 和 NavigableString 对象的实例混合到我的 myBS4 和 myTag 和 myNavigableString 对象树中。当被要求在非扩展节点上执行扩展操作时,调用将失败。
所以覆盖 new_tag() 等可能不够;了解您是否获得所有案例的唯一方法是研究(或 grep)整个 bs4 实现。并且 bs4 更新很可能会破坏它,即使实际上根本没有触及 bs4 本身的概念性理由。
有没有解决这个问题的干净方法?我考虑过mixin,但据我所知,我仍然必须将bs4子类化才能引入mixin,所以它无济于事。我完全错过了什么吗?