Я хотел установить Monkeypatch ElementTree, потому что он слишком ограничен, и у меня есть блок кода, который работает, но я не понимаю его, поэтому он может быть опасным (кросс-платформенный? Проблемы с версией? Неразрешимый? Совместимость с Python4? И т. Д.), поэтому я хотел бы понять это.
ElementTree.Element
не может быть легко обработано, как это реализовано в C (см. Сноску), но «разоблачение скрытого модуля Python работает».Этот следующий фрагмент кода взят из модуля xmlschema
, который случайно и волшебным образом помещен перед импортом в ElementTree, что делает импортируемую ElementTree.Element
обезьяньей заплаткой.Причина в том, что этот фрагмент кода:
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).
Но я не указываю пакет ...
- Не импортирует ли importlib в словаре sys.modules?
- Этот трюк универсально безопасен или опасен?(работает на Mac py 3.7, где
import lxml
терпит неудачу, и Win 3.4, где это работает)
Реализация ET с сноской. Элемент сноски
Это пример неспособности получить monkeypatch ET.Элемент.
>>> 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