lxml.etree._ElementTree.find () не может быть вызван для результата objectify.parse - PullRequest
3 голосов
/ 08 сентября 2011
>>> from lxml import objectify
>>> from StringIO import StringIO
>>> f = StringIO("<root>data</root>")
>>> tree = objectify.parse(f)
>>> type(tree)
<type 'lxml.etree._ElementTree'>
>>> tree.find('root')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lxml.etree.pyx", line 1944, in lxml.etree._ElementTree.find (src/lxml/lxml.etree.c:45105)
TypeError: find() takes exactly one argument (2 given)
>>> tree.find()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lxml.etree.pyx", line 1926, in lxml.etree._ElementTree.find (src/lxml/lxml.etree.c:44970)
TypeError: find() takes at least 1 positional argument (0 given)
>>> print tree.find.__doc__
find(self, path, namespaces=None)

        Finds the first toplevel element with given tag.  Same as
        ``tree.getroot().find(path)``.

        The optional ``namespaces`` argument accepts a
        prefix-to-namespace mapping that allows the usage of XPath
        prefixes in the path expression.

Обратите внимание, что tree.getroot().find работает, а find работает на _ElementTree экземплярах, созданных etree.parse.

Главный вопрос: как один и тот же метод может вызвать эти два взаимоисключающих исключения? Кроме того, хотя я могу использовать tree.getroot().find, предпочтительнее использовать более короткую форму, если она работает так, как задокументировано, поэтому мне интересно, действительно ли это ошибка lxml?

1 Ответ

0 голосов
/ 15 сентября 2011

Мы разгадываем эту загадку, посмотрев на соответствующий источник (да здравствует OSS):

def find(self, path, namespaces=None):
    u"""find(self, path, namespaces=None)

    Finds the first toplevel element with given tag.  Same as
    ``tree.getroot().find(path)``.

    The optional ``namespaces`` argument accepts a
    prefix-to-namespace mapping that allows the usage of XPath
    prefixes in the path expression.
    """
    self._assertHasRoot()
    root = self.getroot()
    if _isString(path):
        start = path[:1]
        if start == u"/":
            path = u"." + path
        elif start == b"/":
            path = b"." + path
    return root.find(path, namespaces)

"lxml.etree.pyx", line 1926 - первая и "lxml.etree.pyx", line 1944 последняя строка фрагмента, так что на самом деледва разных find метода.Очевидно, что objectify создает несколько различных объектов (и, следовательно, это ошибка в lxml), которые не принимают параметр namespaces.Если вы используете lxml.etree.parse для анализа вашего StringIO объекта, API работает просто отлично.

...