Как установить текстовое поле ElementTree Element в конструкторе

Как установить текстовое поле элемента ElementTree из его конструктора? Или, в приведенном ниже коде, почему вторая версия root.text None?

import xml.etree.ElementTree as ET

root = ET.fromstring("<period units='months'>6</period>")
ET.dump(root)
print root.text

root=ET.Element('period', {'units': 'months'}, text='6')
ET.dump(root)
print root.text

root=ET.Element('period', {'units': 'months'})
root.text = '6'
ET.dump(root)
print root.text

Здесь вывод:

<period units="months">6</period>
6
<period text="6" units="months" />
None
<period units="months">6</period>
6

Ответ 1

Конструктор не поддерживает его:

class Element(object):
    tag = None
    attrib = None
    text = None
    tail = None

    def __init__(self, tag, attrib={}, **extra):
        attrib = attrib.copy()
        attrib.update(extra)
        self.tag = tag
        self.attrib = attrib
        self._children = []

Если вы передадите text в качестве аргумента ключевого слова конструктору, вы добавите к элементу атрибут text, что и произошло во втором примере.

Ответ 2

Конструктор не позволяет это, потому что они думали, что было бы нецелесообразно иметь каждый foo=bar добавить атрибут, кроме случайных двух: text и tail

Если вы считаете, что это глупая причина для удаления удобств конструктора (как и я), вы можете создать свой собственный элемент. Я сделал. Я имею это как подкласс и добавил параметр parent. Это позволяет вам все еще использовать его со всем остальным!

Python 2.7:

import xml.etree.ElementTree as ET

# Note: for python 2.6, inherit from ET._Element
#       python 2.5 and earlier is untested
class TElement(ET.Element):
    def __init__(self, tag, text=None, tail=None, parent=None, attrib={}, **extra):
        super(TextElement, self).__init__(tag, attrib, **extra)

        if text:
            self.text = text
        if tail:
            self.tail = tail
        if not parent == None:   # Issues warning if just 'if parent:'
            parent.append(self)

Python 2.6:

#import xml.etree.ElementTree as ET

class TElement(ET._Element):
    def __init__(self, tag, text=None, tail=None, parent=None, attrib={}, **extra):
        ET._Element.__init__(self, tag, dict(attrib, **extra))

        if text:
            self.text = text
        if tail:
            self.tail = tail
        if not parent == None:
            parent.append(self)