Я написал класс, унаследованный от класса xml.etree.ElementTree.Element, чтобы расширить этот класс с помощью методов, чтобы показать полное имя тега элемента etree и простой способ заменить полное содержимое элемента значением XML из строки ..Python, etree: как скопировать экземпляр в новый экземпляр унаследованного класса?
В init метод нового класса я просто хочу иметь копию элемента etree, переданного в качестве параметра при инстанцировании.
Первая попытка была:
def __init__(self, elem):
self = elem
Но тогда "подтеги" список пройденному "Element" заблудился.
Решение ниже работает, но есть ли более «умный» способ скопировать полный «elem» в новый объект?
import xml.etree.ElementTree as ET
#
# this class allows to replace the content including all subelement of an etree element
# by an XML string content
#
class xmltag(ET.Element):
# constructor
def __init__(self, elem):
self.tag = elem.tag
self.text = elem.text
self.attrib = elem.attrib
self.tail = elem.tail
for s in next(elem.iter()):
self.append(s)
# get string of complete start tag name
def __get_tag_start(self):
tag="<"+self.tag
for k in self.attrib.keys():
tag=tag+" "+k+"=\"" + self.attrib[k] + "\""
return tag+">"
# get string of end tag name
def __get_tag_end(self):
return "</" + self.tag + ">" + (self.tail or "")
# get string of whole content between start and end tag
def get_tag_content(self):
content=self.text or ""
for s in next(self.iter()):
xs=xmltag(s)
content=content+xs.__get_tag_start()
content=content+(xs.text or "")
content=content+xs.__get_tag_end()
return content
# change tag name
def set_tag_name(self,tagname):
self.tag=tagname
# change content
def set_tag_content(self,content):
try:
elem=ET.fromstring(self.__get_tag_start()+content+self.__get_tag_end())
self.clear()
self.tag = elem.tag
self.text = elem.text
self.attrib = elem.attrib
self.tail = elem.tail
for s in next(elem.iter()):
self.append(s)
elem.clear()
except:
pass
#
# testdata
#
xmldata="""<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>"""
#
# MAIN
#
if __name__ == "__main__":
root = ET.fromstring(xmldata)
element=root.find("country")
if ET.iselement(element):
x=xmltag(element)
print(x.get_tag_content())
x.set_tag_content("abc")
print(ET.tostring(x,encoding="unicode"))
x.set_tag_content("EFG")
print(ET.tostring(x,encoding="unicode"))
x.set_tag_name("test")
print(ET.tostring(x,encoding="unicode"))
Выполнение 'self = something' ничего не меняет. Вы просто привязываете имя 'self' к чему-то еще на протяжении выполнения' __init__', но вне ссылок не изменяется. Поскольку у вас есть рабочее решение, и вы хотите его улучшить, вероятно, вы должны перенести этот вопрос на codereview SE. – Bakuriu
Возможный дубликат [классы в Python для новичков] (http://stackoverflow.com/questions/7993089/classes-in-python-for-a-beginner) –