【问题标题】:Python ElementTree: ElementTree vs root ElementPython ElementTree:ElementTree 与根元素
【发布时间】:2015-09-16 23:15:13
【问题描述】:

我对 Python ElementTree API 中的一些设计决策感到有些困惑 - 它们似乎有点武断,所以我想澄清一下这些决策背后是否有一些逻辑,或者它们是否是或多或少是临时的。

因此,通常有两种方法可以生成ElementTree - 一种是通过某种源流,如文件或其他 I/O 流。这是通过parse() 函数或ElementTree.parse() 类方法实现的。

另一种方法是直接从字符串对象加载 XML。这可以通过fromstring() 函数完成。

好的,太好了。现在,我认为这些函数在返回的内容方面基本上是相同的——它们两者之间的区别基本上是输入源(一个接受文件或流对象,另一个接受纯字符串。)除了出于某种原因,parse() 函数返回一个 ElementTree 对象,但 fromstring() 函数返回一个 Element 对象。区别基本上在于Element 对象是XML 树的root 元素,而ElementTree 对象是围绕根元素的某种“包装器”,它提供了一些额外的功能。您始终可以通过调用getroot()ElementTree 对象中获取根元素。

不过,我还是很困惑为什么我们会有这种区别。为什么fromstring()直接返回一个根元素,而parse()返回一个ElementTree对象?这种区别背后有什么逻辑吗?

【问题讨论】:

  • 老实说,ElementTree API 有时会做出一些非常奇怪的决定,这就是其中之一。
  • 我使用 lxml 并且 api 是相同的。我也想知道这些问题的答案。我倾向于将事情保持在包装级别,但我不知道为什么。
  • ElementTree 比 Element 有更多的功能,尤其是 write()。我并不是说不能为 Element 提供这些,但它们是主要的区别。 fromstring() 只给你一个 Element 可以有效地防止你更改和编写树。

标签: python


【解决方案1】:

一个美丽的答案来自这个老discussion

仅作记录:Fredrik [ElementTree 的创建者] 实际上并不认为它是一种设计 “怪癖”。他认为它是为不同的用例设计的。尽管 parse() 解析一个文件,该文件通常包含一个完整的文档 (在 ET 中表示为 ElementTree 对象),fromstring() 和 特别是'literal wrapper' XML() 用于解析字符串, 其中(大多数?)通常只包含 XML 片段。用一个片段,你 通常想继续做一些事情,比如将它插入另一个 树,因此几乎在所有情况下都需要顶级元素。

还有:

为什么 et.parse 不是唯一的方法呢?为什么有 XML 或 fromstring 有吗?

好吧,用例。 XML() 是 fromstring() 的别名,因为它是 写起来方便(并且可读性好)

section = XML('A 到 Z') section.append(段落)

用于源代码中的 XML 文字。 fromstring() 在那里,因为当 你想从你得到的字符串中解析一个片段 来源,很容易用这个函数来表达,就像

    el = fromstring(some_string)

如果要从文件或类似文件的对象中解析文档,请使用 解析()。三个用例,三个功能。第四个用例 从字符串中解析文档没有自己的功能, 因为写起来很简单

    tree = parse(BytesIO(some_byte_string))

【讨论】:

    【解决方案2】:

    我的想法与 cmets 中的 remram 相同:parse 获取文件位置或文件对象并保留该信息,以便它可以提供额外的实用程序,这真的很有帮助。如果 parse 没有返回 ET 对象,那么您必须更好地跟踪源和诸如此类的东西,以便手动将它们反馈回 ET 对象默认具有的辅助函数。与文件相比,字符串 - 根据定义 - 没有附加相同类型的信息,因此您不能为它们创建相同的实用程序(否则很可能会有一个 ET.parsefromstring() 方法将返回一个 ET 对象)。

    我怀疑这也是将方法命名为 parse 而不是 ET.fromfile() 背后的逻辑:我希望从 返回相同的对象类型em>fromfilefromstring,但不能说我对 parse 有同样的期望(自从我开始使用 ET 已经很长时间了,所以有无法验证,但这是我的感觉)。

    关于 Remram 提出的在 Elements 上放置实用方法的主题,据我了解文档,Elements 在实现方面非常统一。人们谈论“根元素”,但树根的元素在其类属性和方法方面与所有其他元素实际上是相同的。据我所知,Elements 甚至不知道他们的父母是谁,这很可能支持这种统一性。否则可能会有更多代码来实现“根”元素(没有父元素)或重新父子元素。在我看来,Element 类的简单性对其大有裨益。所以对我来说,让 Elements 在很大程度上不知道它们上面的任何东西(它们的父级,它们来自的文件)似乎更好,这样就不会有任何关于 4 个 Elements 在同一棵树(或类似树)中具有不同输出文件的问题。

    当涉及在代码中实现模块时,在我看来,脚本必须在某些时候以一种或另一种方式将输入识别为文件(否则它会尝试将文件传递给 来自字符串)。所以不应该出现 parse 的输出应该是意外的情况,这样 ElementTree 被假定为一个元素并被处理(当然,除非 parse em> 是在没有程序员检查 parse 做了什么的情况下实现的,这对我来说似乎是个坏习惯)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 1970-01-01
      • 2016-09-18
      相关资源
      最近更新 更多