继承或模拟 pythons etree.ElementTree.Element 可能吗?
Inherit or mock pythons etree.ElementTree.Element possible?
我正在尝试为 python 的 xml.etree.ElementTree
中的 ElementTree
和 Element
创建一个小插件,它允许像这样的符号:
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.parse
、ET.fromstring
、ET.ElementTree.find
等将始终 return 内部 Element
和 ElementTree
对象.
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?
无法覆盖 class,因为 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')
我遇到了类似的问题,我无意中找到了一个快速解决方法:
我在 Python 3.7 之前的版本中导入了 xmlschema
,使用 setattr
.
进行猴子修补 ET.Element
没有任何问题
编辑:因为这很有趣,所以我进一步研究了它。这里是 how to monkeypatch ElementTree.
我正在尝试为 python 的 xml.etree.ElementTree
中的 ElementTree
和 Element
创建一个小插件,它允许像这样的符号:
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.parse
、ET.fromstring
、ET.ElementTree.find
等将始终 return 内部 Element
和 ElementTree
对象.
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?
无法覆盖 class,因为 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')
我遇到了类似的问题,我无意中找到了一个快速解决方法:
我在 Python 3.7 之前的版本中导入了 xmlschema
,使用 setattr
.
ET.Element
没有任何问题
编辑:因为这很有趣,所以我进一步研究了它。这里是 how to monkeypatch ElementTree.