Как было указано, это зависит от типа. Для встроенных типов данных лучше всего перейти по значению.
Вот пример, предположим, что у вас есть целочисленное значение, и вы хотите передать его другой процедуре. Если это значение было оптимизировано для хранения в регистре, то, если вы хотите передать его ссылкой, оно сначала должно быть сохранено в памяти, а затем указателем на эту память, помещенную в стек для выполнения вызова. Если он передается по значению, все, что требуется, - это регистр, вставленный в стек. (Подробности немного сложнее, чем при использовании разных систем вызова и процессоров).
Если вы занимаетесь программированием шаблонов, вы обычно вынуждены всегда передавать const ref, поскольку вы не знаете типов Передача штрафов за передачу чего-то плохого по значению намного хуже, чем штрафы за прохождение встроенного типа по const ref.
Вы хотите тонкий шпон? Это легко приготовить. Попробуйте в качестве начала следующую тривиальную оболочку вокруг ElementTree:
# geetree.py
import xml.etree.ElementTree as ET
class GeeElem(object):
"""Wrapper around an ElementTree element. a['foo'] gets the
attribute foo, a.foo gets the first subelement foo."""
def __init__(self, elem):
self.etElem = elem
def __getitem__(self, name):
res = self._getattr(name)
if res is None:
raise AttributeError, "No attribute named '%s'" % name
return res
def __getattr__(self, name):
res = self._getelem(name)
if res is None:
raise IndexError, "No element named '%s'" % name
return res
def _getelem(self, name):
res = self.etElem.find(name)
if res is None:
return None
return GeeElem(res)
def _getattr(self, name):
return self.etElem.get(name)
class GeeTree(object):
"Wrapper around an ElementTree."
def __init__(self, fname):
self.doc = ET.parse(fname)
def __getattr__(self, name):
if self.doc.getroot().tag != name:
raise IndexError, "No element named '%s'" % name
return GeeElem(self.doc.getroot())
def getroot(self):
return self.doc.getroot()
Вы вызываете ее так:
>>> import geetree
>>> t = geetree.GeeTree('foo.xml')
>>> t.xml_api_reply.weather.forecast_information.city['data']
'Mountain View, CA'
>>> t.xml_api_reply.weather.current_conditions.temp_f['data']
'68'
Я нашел следующий модуль python-simplexml , который в попытках автора получить что-то похожее на SimpleXML из PHP действительно является small wrapper around ElementTree
. Это менее 100 строк, но, кажется, делает то, что было запрошено:
>>> import SimpleXml
>>> x = SimpleXml.parse(urllib.urlopen('http://www.google.com/ig/api?weather=94043'))
>>> print x.weather.current_conditions.temp_f['data']
58
Если вы не возражаете против использования сторонней библиотеки, то BeautifulSoup выполнит почти то, что вы просите:
>>> from BeautifulSoup import BeautifulStoneSoup
>>> soup = BeautifulStoneSoup('''<snip>''')
>>> soup.xml_api_reply.weather.current_conditions.temp_f['data']
u'68'
Проект suds предоставляет клиентскую библиотеку веб-служб, которая работает почти так же, как вы описываете - предоставьте ей wsdl, а затем используйте фабричные методы для создания определенных типов (и обработки ответов тоже!).
lxml уже упоминался. Вы также можете проверить lxml.objectify для некоторых действительно простых манипуляций.
>>> from lxml import objectify
>>> tree = objectify.fromstring(your_xml)
>>> tree.weather.attrib["module_id"]
'0'
>>> tree.weather.forecast_information.city.attrib["data"]
'Mountain View, CA'
>>> tree.weather.forecast_information.postal_code.attrib["data"]
'94043'
Если вы еще не сделали этого, я бы посоветовал изучить DOM API для Python. DOM - это довольно широко используемая система интерпретации XML, поэтому он должен быть довольно надежным.
Возможно, она немного сложнее, чем то, что вы описали, но это происходит скорее от попыток сохранить всю информацию, скрытую в XML-разметке, чем от плохого дизайна.
Взгляните на Amara 2, особенно на Bindery часть этого руководства .
Это работает примерно так, как вы описываете.
С другой стороны. Методы ElementTree find * () могут дать вам 90% этого и поставляются вместе с Python.
Я считаю, что встроенный xml-модуль python сделает свое дело. Посмотрите "xml.parsers.expat"
Я настоятельно рекомендую lxml.etree и xpath для синтаксического анализа и анализа ваших данных. Вот полный пример. Я обрезал xml, чтобы его было легче читать.
import lxml.etree
s = """<?xml version="1.0" encoding="utf-8"?>
<xml_api_reply version="1">
<weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" >
<forecast_information>
<city data="Mountain View, CA"/> <forecast_date data="2010-06-23"/>
</forecast_information>
<forecast_conditions>
<day_of_week data="Sat"/>
<low data="59"/>
<high data="75"/>
<icon data="/ig/images/weather/partly_cloudy.gif"/>
<condition data="Partly Cloudy"/>
</forecast_conditions>
</weather>
</xml_api_reply>"""
tree = lxml.etree.fromstring(s)
for weather in tree.xpath('/xml_api_reply/weather'):
print weather.find('forecast_information/city/@data')[0]
print weather.find('forecast_information/forecast_date/@data')[0]
print weather.find('forecast_conditions/low/@data')[0]
print weather.find('forecast_conditions/high/@data')[0]