Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>@mattbasta has the right idea here. However, I want to propose something a bit different: implement <code>to_string</code> using <code>cElementTree.TreeBuilder</code>. I don't know if the super-fast serialization of ElementTree will win out against overhead of creating an ElementTree.</p> <p>Here is a wonky <code>TAG</code> class with a <code>to_string_b()</code> method that makes use of some micro-optimizations and uses a TreeBuilder to build the tree. (A possibly-important difference between your <code>to_string()</code> and TreeBuilder is that TreeBuilder will always escape output for XML, whereas yours will not.)</p> <pre><code>import xml.etree.cElementTree as ET class TAG(object): def __init__(self, tag="TAG", contents=None, **attributes): self.tag = tag # this is to insure that `contents` always has a uniform # type. if contents is None: self.contents = [] else: if isinstance(contents, basestring): # I suspect the calling code passes in a string as contents # in the common case, so this means that each character of # the string will be yielded one-by-one. let's avoid that by # wrapping in a list. self.contents = [contents] else: self.contents = contents self.attributes = attributes def to_string(self): yield '&lt;{}'.format(self.tag) for (a, v) in self.attributes.items(): yield ' {}="{}"'.format(a, v) if self.contents is None: yield '/&gt;' else : yield '&gt;' for c in self.contents: if isinstance(c, TAG): for i in c.to_string(): yield i else: yield c yield '&lt;/{}&gt;'.format(self.tag) def to_string_b(self, builder=None): global isinstance, basestring def isbasestring(c, isinstance=isinstance, basestring=basestring): # some inlining return isinstance(c, basestring) if builder is None: iamroot = True builder = ET.TreeBuilder() else: iamroot = False #don't close+flush the builder builder.start(self.tag, self.attributes) if self.contents is not None: for c in self.contents: if (isbasestring(c)): builder.data(c) else: for _ in c.to_string_b(builder): pass builder.end(self.tag) # this is a yield *ONLY* to preserve the interface # of to_string()! if you can change the calling # code easily, use return instead! if iamroot: yield ET.tostring(builder.close()) class H1(TAG): def __init__(self, contents=None, **attributes): TAG.__init__(self, 'H1', contents, **attributes) class H2(TAG): def __init__(self, contents=None, **attributes): TAG.__init__(self, 'H2', contents, **attributes) tree = H1(["This is some ", H2("test input", id="abcd", cls="efgh"), " and trailing text"]) print ''.join(tree.to_string()) print ''.join(tree.to_string_b()) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload