2015-06-08 35 views
1

我想向来自lxml的html树添加一些功能。如何间接创建对象时创建子类

因此,我想添加一个类,使用super().__init__()并添加额外的功能,例如为每个节点添加深度,为isLeafNode添加布尔值,并实现view方法。

这就是问题出现的地方,因为我可能会使用lxml.html.fromstring('<p>test</p>')来初始化lxml类。

这是我走到这一步:

class Elhanced(lxml.etree._ElementTree): 
    def __init__(self, htmlString): 
     super().__init__() 
     self.x = 'useful' 
     self.tree = lxml.html.fromstring(htmlString) # Issue 

    def useful_function(): 
     pass 

不过,其实我是想的对象与附加功能增强 lxml的对象,而不是树通过self.tree可访问,而其他属性可通过self获取。

如何将功能添加到增强的lxml对象?

我想初始化是这样的:

el = Elhanced('<p>test</p>') 

其中el具有lxml(如el.xpath应该存在)的所有方法,以及el.useful_function()el.x

也许现在还没有更好的方法。

+0

或许'super().__ init __()'没有达到你期望的效果;你可以使用'super(Elhanced,self)'来访问超类。例如,要调用'__init __()',你可以使用'super(Elhanced,self).__ init __()'。 – Quint

+2

@Quintus在python3中,'super()'应该可以正常工作。这与OP的问题没有任何关系。 – deets

+0

为什么你不使用包装类?或者如果它是一个你想添加的函数,只需从那里调用它:'useful_function(el,arg1,arg2)'。 – solarc

回答

2

你只是使用继承 - 没有必要担心维护一个agregate self.tree实例:只要你不重写它,你的子类就会具有原始超类的行为。

唯一非直接的部分正是由于某种原因,lxml库被设计为使您难以给它提供一个简单的字符串来解析(从而提供外部工厂fromstring)。

如果您使用类似文件的对象调用实例parse方法,则可以完成解析 - 因此在调用parse之前,必须将纯字符串转换为该字符串。是的,它可以在__init__内完成。试试吧:

import lxml.etree 
# Python 2/3 compatibility 
try: 
    from StringIO import StringIO 
except ImportError: 
    from io import StringIO 

class Elhanced(lxml.etree._ElementTree): 
    def __init__(self, htmlString): 
     super(Elhanced, self).__init__() 
     self.x = 'useful' 
     self.parse(StringIO(htmlString), lxml.etree.HTMLParser()) 

    def useful_function(): 
     pass 
+0

哇,这太棒了!非常感谢:我已经放弃了希望。我编辑了最后的几位(还有一个括号缺失)。 – PascalVKooten