Лучший способ представить это, используя структуры данных Python - PullRequest
1 голос
/ 05 июня 2011
  <specification> 
    <propertyName> string </propertyName>
    <value> 
      <number> 
        <value> anyNumberHere </value>
      </number>
      <text> 
        <value> anyTextHere </value>
      </text>
      <URL> 
        <value> anyURIHere </value>
      </URL>
    </value>
    <!-- ... 1 or more value nodes here ... -->
  </specification>
  <!-- ... 1 or more specification nodes here ... -->

Мне нужно построить этот запрос для API, где пользователь будет передавать эти значения.Итак, что должно быть лучшим способом представить это, чтобы пользователю метода было легко передать соответствующие значения в операцию?

Я думаю:

Список Dicts:

[specification1, specification2, specification3]

Где:

specification1= [value1, value2]

Где:

value1 = {number:anyNumberHere, text:anyTextHere, URL:anyURIHere}
value2 = {number:anyNumberHere, text:anyTextHere, URL:anyURIHere}

Но я не могу разместить:<propertyName> здесь.Любые предложения?

Более того, это звучит сложно.Можем ли мы иметь инкапсуляцию объекта, как мы делаем это в Java?Я понимаю, мы можем, но мне любопытно, каков рекомендуемый способ в python?

My logic for now, suggestions (incorrect due to propertyName):
    #specification is a List of List of Dicts
    for spec in specification:
        specification_elem = etree.SubElement(root, "specification")
        propertyName_elem = etree.SubElement(specification_elem,"propertyName")
        propertyName_elem.text = spec_propertyName

        for value in spec:
            value_elem = etree.SubElement(specification_elem, "value")
            for key in value:
                key_elem = etree.SubElement(value_elem, key)
                keyValue_elem = etree.SubElement(key_elem, "value")
                keyValue_elem.text = value[key]

Здесь я передам spec_propertyName, в качестве параметра diff.Итак, пользователь пройдет: specification and spec_propertyName

Ответы [ 3 ]

6 голосов
/ 05 июня 2011

Как насчет списка объектов Спецификации, каждый из которых имеет property_name и список value словарей?(values может быть списком объектов вместо словарей.)

Например:

class Value(object):
    def __init__(self,
                 number=None,
                 text=None,
                 url=None):
        self.number = number
        self.text = text
        self.url = url

class Specification(object):
    def __init__(self, propertyName):
        self.propertyName = propertyName
        self.values = []

spec1 = Specification("Spec1")
spec1.values = [Value(number=3,
                      url="http://www.google.com"),
                Value(text="Hello, World!",
                      url="http://www.jasonfruit.com")]

spec2 = Specification("Spec2")
spec2.values = [Value(number=27,
                      text="I can haz cheezburger?",
                      url="http://stackoverflow.com"),
                Value(text="Running out of ideas.",
                      url="http://news.google.com")]
0 голосов
/ 05 июня 2011

Вот подход к представлению с использованием именованных кортежей . Вы можете перейти на использование классов (добавление кода для некоторой проверки входных данных вызывающего абонента и разрешение пропуска field=None для необязательных полей) на досуге без каких-либо других изменений пользовательского API и небольших изменений в строительном коде ElementTree. .

# -*- coding: cp1252 -*-

from collections import namedtuple
import xml.etree.cElementTree as etree

Specifications = namedtuple('Specifications', 'specification_list')
Specification = namedtuple('Specification', 'propertyName value_list')
Value = namedtuple('Value', 'number text url')

def make_etree(specifications, encoding):
    """ 
    Convert user's `specifications` to an ElementTree.
    `encoding` is encoding of *input* `str` objects.
    """
    def ensure_unicode(v):
        if isinstance(v, str): return v.decode(encoding)
        if isinstance(v, unicode): return v
        return unicode(v) # convert numbers etc to unicode strings  

    root = etree.Element('specifications')
    for spec in specifications.specification_list:
        specification_elem = etree.SubElement(root, "specification")
        propertyName_elem = etree.SubElement(specification_elem, "propertyName")
        propertyName_elem.text = ensure_unicode(spec.propertyName)
        for value in spec.value_list:
            value_elem = etree.SubElement(specification_elem, "value")
            for key in value._fields:
                kv = getattr(value, key)
                if kv is None: continue
                key_elem = etree.SubElement(value_elem, key)
                keyValue_elem = etree.SubElement(key_elem, "value")
                keyValue_elem.text = ensure_unicode(kv)
    return etree.ElementTree(root)

# === sample caller code follows ===

specs = Specifications(
    specification_list=[
        Specification(
            propertyName='a prop',
            value_list=[
                Value(
                    number=42,
                    text='universe', 
                    url='http://uww.everywhere',
                    ),
                Value(
                    number=0,
                    text=None, # optional
                    url='file:///dev/null',
                    ),
                ],
            ),
        Specification(
            propertyName='b prop',
            value_list=[
                Value(
                    number=1,
                    text='Üñîçøðè', # str object, encoded in cp1252
                    url=u'Üñîçøðè', # unicode object
                    ),
                ],           
            ),
        ],
    )

print repr(specs); print

import sys
tree = make_etree(specs, 'cp1252')
import cStringIO
f = cStringIO.StringIO()
tree.write(f, encoding='UTF-8', xml_declaration=True)
print repr(f.getvalue())
print

Вывод (в столбце 80):

Specifications(specification_list=[Specification(propertyName='a prop', value_li
st=[Value(number=42, text='universe', url='http://uww.everywhere'), Value(number
=0, text=None, url='file:///dev/null')]), Specification(propertyName='b prop', v
alue_list=[Value(number=1, text='\xdc\xf1\xee\xe7\xf8\xf0\xe8', url=u'\xdc\xf1\x
ee\xe7\xf8\xf0\xe8')])])

"<?xml version='1.0' encoding='UTF-8'?>\n<specifications><specification><propert
yName>a prop</propertyName><value><number><value>42</value></number><text><value
>universe</value></text><url><value>http://uww.everywhere</value></url></value><
value><number><value>0</value></number><url><value>file:///dev/null</value></url
></value></specification><specification><propertyName>b prop</propertyName><valu
e><number><value>1</value></number><text><value>\xc3\x9c\xc3\xb1\xc3\xae\xc3\xa7
\xc3\xb8\xc3\xb0\xc3\xa8</value></text><url><value>\xc3\x9c\xc3\xb1\xc3\xae\xc3\
xa7\xc3\xb8\xc3\xb0\xc3\xa8</value></url></value></specification></specification
s>"
0 голосов
/ 05 июня 2011

Если propertyNames уникальны, вы можете иметь список адресов.Если это не так, у вас может быть список из списка списков диктов.

Если все эти списки в конечном итоге трудно отслеживать, вы можете создать класс для хранения данных:

class Specification:
    def __init__(self):
        self.propertyName = ""
        self.values = []

Затем используйте:

spec = Specification()
spec.propertyName = "string"
value = {"URL":"someURI", "text":"someText"}
spec.values.append(value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...