2012-12-16

Python: cElementTree returns non open object

xml.etree.cElementTree は、xml.etree.ElementTree の C 実装だ。

ElementTree クラスはエレメントの構造を包み込み、それと XML を行き来するのに使えます。

この API の C 実装である xml.etree.cElementTree も使用可能です。

C 実装であること以外、ElementTree と cElementTree の違いについては述べられていない。違いがないなら、C 実装の方を使わない手はない。しかし、

$ python
Python 2.6.6 (r266:84292, Sep 12 2011, 14:03:14)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.ElementTree
>>> html = '<html></html>'
>>> tree = xml.etree.ElementTree.fromstring(html)
>>> tree.html = html
>>> tree.html
'<html></html>'
$ python
Python 2.6.6 (r266:84292, Sep 12 2011, 14:03:14)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.cElementTree
>>> html = '<html></html>'
>>> tree = xml.etree.cElementTree.fromstring(html)
>>> tree.html = html
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: html

cElementTree が返すオブジェクトはオープン・オブジェクトではないらしく、属性を追加することができない。C 実装されたモジュールとはそういうもんか、とも思ったが、

$ python
Python 2.6.6 (r266:84292, Sep 12 2011, 14:03:14)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cProfile
>>> p = cProfile.Profile()
>>> p.foo = 'foo'
>>> p.foo
'foo'

同じ C 実装モジュールの cProfile では問題ない。想像するに、ElementTree の場合、木構造で大量のオブジェクトを使用するためメモリをケチってるのかも知れない。

ともかく、RHEL5 + elementtree で作ったスクリプトを RHEL6 で動そうと喜んで cElementTree を使った私にとっては、この上ないぬか喜びだった。