Python ElementTree:ElementTree vs根元素
我对Python ElementTree API中的一些设计决定感到有点困惑 - 它们看起来有些随意,所以我想澄清一下,看看这些决定是否有一些逻辑背后的原因,或者它们更多,或者不那么特别。
因此,通常有两种方法可能需要生成ElementTree
- 一种是通过某种源流(如文件或其他I / O流)生成的。 这是通过parse()
函数或ElementTree.parse()
类的方法实现的。
另一种方法是直接从字符串对象加载XML。 这可以通过fromstring()
函数完成。
好的,太好了。 现在,我认为这些函数在返回的内容上基本相同 - 两者之间的区别基本上是输入源(一个接受文件或流对象,另一个接受普通字符串)。除了某些原因parse()
函数返回一个ElementTree
对象,但fromstring()
函数返回一个Element
对象。 区别在于Element
对象是XML树的根元素,而ElementTree
对象是根元素周围的“包装器”,它提供了一些额外的功能。 您可以通过调用getroot()
从ElementTree
对象获取根元素。
不过,我很困惑为什么我们有这个区别。 为什么fromstring()
直接返回一个根元素,但是parse()
返回一个ElementTree
对象? 这种区别背后有逻辑吗?
这个古老的讨论来自一个美丽的答案:
仅供参考:Fredrik [ElementTree的创造者]实际上并不认为它是一种设计“怪癖”。 他认为它是为不同的用例设计的。 虽然parse()解析通常包含完整文档(在ET中表示为ElementTree对象)的文件,但是fromstring()特别是'literal wrapper'XML()是为了解析字符串而创建的,常常包含XML片段。 有了一个片段,你通常想继续做一些事情,比如将其插入到另一个树中,因此几乎在所有情况下都需要顶层元素。
和:
为什么不是唯一的方法来做到这一点? 为什么要有XML或fromstring?
那么,用例。 XML()是fromstring()的别名,因为编写方便(且可读性强)
section = XML('A到Z')section.append(段落)
用于源代码中的XML文字。 fromstring()在那里,因为当你想从你从任何源获得的字符串解析一个片段时,很容易用这个函数来表示它,就像
el = fromstring(some_string)
如果您想从文件或文件类对象中解析文档,请使用parse()。 三个用例,三个功能。 从字符串解析文档的第四种用例没有自己的功能,因为写入操作很简单
tree = parse(BytesIO(some_byte_string))
我在评论中的想法与remram相同:解析需要一个文件位置或一个文件对象,并保留该信息以便它可以提供额外的实用程序,这非常有用。 如果解析没有返回一个ET对象,那么你将不得不更好地跟踪这些源,以及为了将它们手动馈送回默认情况下ET对象所具有的帮助函数。 与文件相反,字符串 - 根据定义 - 没有从它们附加的相同类型的信息,因此您不能为它们创建相同的实用程序(否则很可能会有一个ET.parsefromstring()方法,它将返回ET对象)。
我怀疑这也是被命名为parse而不是ET.fromfile()的方法背后的逻辑:我期望从fromfile和fromstring返回相同的对象类型,但不能说我会期望从解析中得到相同的结果(它是自从我开始使用ET以来已经很长时间了,所以没有办法验证,但这是我的感觉)。
关于在Elements上放置实用方法的Remram提出的主题,据我了解的文档,元素在实现时非常统一。 人们谈论“根元素”,但树根部的元素在其类属性和方法方面与所有其他元素完全相同。 据我所知,元素甚至不知道他们的父母是谁,这可能会支持这种一致性。 否则,可能会有更多的代码来实现“根”元素(没有父项)或重新保留子元素。 在我看来,Element类的简单性大大有利于它。 所以对我来说,离开元素主要是不知道它们之上的任何东西(它们的父代,它们来自哪个文件)似乎更好,所以在同一棵树中(或类似的)不能有任何关于具有不同输出文件的4个元素的障碍。
在代码中实现模块时,在我看来,脚本将不得不在某个点以某种方式将输入识别为文件(否则它会尝试将文件传递给fromString)。 所以不应该出现这样一种情况,即解析输出应该是意料之外的,这样ElementTree被假定为一个元素并按照这种方式处理(当然,除非程序员检查是否执行了解析,这对我来说只是一个不好的习惯)。
链接地址: http://www.djcxy.com/p/29049.html