首页 > 解决方案 > 这个技巧如何通过删除 C 库来暴露 Python 库?(允许猴子修补 ElementTree)

问题描述

我想对 ElementTree 进行猴子补丁,因为它太有限了,而且我有一段代码可以工作,但我不明白,所以可能很危险(跨平台?版本问题?已弃用?Python4 兼容性?等等),所以我想了解它。

ElementTree.Element由于它是在 C 中实现的(见脚注),因此不能轻易修补,但“暴露隐藏的 Python 模块有效”。以下代码块来自 module xmlschema,它意外且神奇地放置在 ElementTree 的导入之前,使导入的ElementTree.Elementmonkeypatchable。这段代码的原因是:

import sys, importlib
sys.modules.pop('xml.etree.ElementTree', None)
sys.modules['_elementtree'] = None
ET = importlib.import_module('xml.etree.ElementTree')

因此,该模块正在从系统中删除。但是无论如何 importlib 都会导入它。

文档说:

这两个函数最重要的区别是import_module()返回的是指定的包或模块(如pkg.mod),而import ()返回的是顶层包或模块(如pkg)。

但我没有指定一个包......

C 实现的 ET.element 脚注

这是无法对 ET.Element 进行猴子补丁的示例。

>>> import xml.etree.ElementTree as ET
>>> ET.Element.new = 'anything'
TypeError: can't set attributes of built-in/extension type 'xml.etree.ElementTree.Element'
class newElement(ET.Element):
    new = 'hello world'
>>> ET.Element = newElement
>>> elem = ET.fromstring('<xml><hello>world</hello></xml>')
AttributeError: 'xml.etree.ElementTree.Element' object has no attribute 'new'
>>> type(newElement()) # should be
>>> type(elem) # but isn't

标签: pythonxmlpython-3.xpython-import

解决方案


推荐阅读