【问题标题】:Inherit or mock pythons etree.ElementTree.Element possible?继承或模拟 python etree.ElementTree.Element 可能吗?
【发布时间】:2015-05-16 17:14:35
【问题描述】:

我正在尝试在 python 的 xml.etree.ElementTree 中为 ElementTreeElement 创建一个小插件,这将允许如下符号:

root = ET.fromstring('<root><a><b attr1="2"/></a></root>')
element1 = root.a
element2 = root.a.b
attr = root.a.b.attr

我试过了:

import xml.etree.ElementTree as _ET

def __getattr__(self, key):
    return self.find('./' + key)

class ElementTree(_ET.ElementTree):
    __getattr__ = __getattr__


class Element(_ET.Element):
    __getattr__ = __getattr__

但这不起作用,因为ET.parseET.fromstringET.ElementTree.find 等将始终返回内部ElementElementTree 对象。

Monkeypatching 类也不起作用:

>>> xml.etree.ElementTree.Element.__getattr__ = lambda x: x
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-bacb0a64c2e5> in <module>()
----> 1 xml.etree.ElementTree.Element.__getattr__ = lambda x: x

TypeError: can't set attributes of built-in/extension type 'xml.etree.ElementTree.Element'

不复制python etree模块然后添加__getattr__是否可行?

相关:How to inherit ElementTree.Element class in python?

【问题讨论】:

    标签: python xml xml.etree


    【解决方案1】:

    由于import of the Element and XMLParser's C implementation,无法覆盖该类:

    # Import the C accelerators
    try:
        # Element is going to be shadowed by the C implementation. We need to keep
        # the Python version of it accessible for some "creative" by external code
        # (see tests)
        _Element_Py = Element
    
        # Element, SubElement, ParseError, TreeBuilder, XMLParser
        from _elementtree import *
    except ImportError:
        pass
    

    模块_elementtree位于Modules/_elementtree.c

    一种解决方案是复制 python etree 模块,并将导入更改为:

    _Element_Py = Element
    

    我对此做了一个简单的实现:https://github.com/arve0/objectifiedetree

    这样使用:

    from objectifiedetree import *
    
    tree = ET.parse('/path/to/file.xml')
    # dot notation :-)
    el = tree.xpath.to.your.element
    
    # use normal etree attributes
    print(el.attrib)
    
    # access name crashes
    attrib_el = el.find('./attrib')
    

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题,我不小心找到了一个快速解决方法:
      我在 Python 3.7 之前的版本中导入了 xmlschema,并且在使用 setattr 进行猴子修补时没有问题。

      编辑:由于这很有趣,我已经进一步研究了它。这里是how to monkeypatch ElementTree

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-24
        • 2011-07-25
        • 2019-06-26
        • 1970-01-01
        • 2018-02-08
        • 1970-01-01
        • 1970-01-01
        • 2011-02-13
        相关资源
        最近更新 更多