2013-07-10 70 views
4

我有一些数据来自SOAP API,使用Suds,我需要在我的Python脚本中解析这些数据。之前我去,并且写一个解析器(还有比这只是一个做多):将SOAP复杂数据类型解析为Python字典

1) 有谁认识这是什么? 这是由Suds(documentation)返回的标准复杂对象数据类型。应该有发现。

2) 如果是的话,是没有办法,我可以用它来将其转换为一个Python字典现有的库? 如何将此对象解析为Python字典?看起来我可以将字典传递给Suds,但看不到一个简单的方法让一个退出。

(ArrayOfBalance){ 
    Balance[] = 
     (Balance){ 
     Amount = 0.0 
     Currency = "EUR" 
     }, 
     (Balance){ 
     Amount = 0.0 
     Currency = "USD" 
     }, 
     (Balance){ 
     Amount = 0.0 
     Currency = "GBP" 
     }, 
} 
+0

哇..我可以诚实地说,在这20年中,我从来没有见过这种形式的序列化。现在我必须知道那是什么。你能给我们一个关于数据的背景吗? –

+0

很高兴它不只是我!这是来自[OKPay的API]的钱包平衡响应(https://www.okpay.com/en/developers/interfaces/functions/wallet-get-balance.html) –

+0

这似乎是一些自制的数据结构: - \我怀疑是 – tamasgal

回答

4

正确的答案,往往是这样,是in the docs。 (括号内)是可以包含其他对象或类型的对象。

在这种情况下,我们有一个ArrayOfBalance对象包含Balance类型,每种类型都有的AmountCurrency属性的列表。

这些都可以被称为使用.符号所以下面的单行的伎俩。

balance = {item.Currency: item.Amount for item in response.Balance} 
3

我遇到了类似的问题,不得不读泡沫响应。 Suds响应将作为由对象组成的元组返回。 len(响应)将显示包含在泡沫响应元组中的对象的数量。 为了访问第一个对象,我们需要给response[0]

在IDLE如果键入>>>print response[0]后跟一个句点“”符号,您将看到一个弹出窗口,显示可从此级别访问的各种对象。

例如:如果输入response[0]。它会带来一个弹出窗口并显示Balance对象,所以命令现在变成response[0].Balance

您可以按照同样的方法来获得下后续级别

3

找到一个solution对象的列表:

from suds.sudsobject import asdict 

def recursive_asdict(d): 
    """Convert Suds object into serializable format.""" 
    out = {} 
    for k, v in asdict(d).iteritems(): 
     if hasattr(v, '__keylist__'): 
      out[k] = recursive_asdict(v) 
     elif isinstance(v, list): 
      out[k] = [] 
      for item in v: 
       if hasattr(item, '__keylist__'): 
        out[k].append(recursive_asdict(item)) 
       else: 
        out[k].append(item) 
     else: 
      out[k] = v 
    return out 

def suds_to_json(data): 
    return json.dumps(recursive_asdict(data)) 

如果潜艇只是嵌套的字典和列表,它应该工作。

5

您可以将对象强制转换为dict(),但您仍然可以使用泡沫使用的复杂数据类型。因此,这里是我的场合写了一些有用的功能:

def basic_sobject_to_dict(obj): 
    """Converts suds object to dict very quickly. 
    Does not serialize date time or normalize key case. 
    :param obj: suds object 
    :return: dict object 
    """ 
    if not hasattr(obj, '__keylist__'): 
     return obj 
    data = {} 
    fields = obj.__keylist__ 
    for field in fields: 
     val = getattr(obj, field) 
     if isinstance(val, list): 
      data[field] = [] 
      for item in val: 
       data[field].append(basic_sobject_to_dict(item)) 
     else: 
      data[field] = basic_sobject_to_dict(val) 
    return data 


def sobject_to_dict(obj, key_to_lower=False, json_serialize=False): 
    """ 
    Converts a suds object to a dict. 
    :param json_serialize: If set, changes date and time types to iso string. 
    :param key_to_lower: If set, changes index key name to lower case. 
    :param obj: suds object 
    :return: dict object 
    """ 
    import datetime 

    if not hasattr(obj, '__keylist__'): 
     if json_serialize and isinstance(obj, (datetime.datetime, datetime.time, datetime.date)): 
      return obj.isoformat() 
     else: 
      return obj 
    data = {} 
    fields = obj.__keylist__ 
    for field in fields: 
     val = getattr(obj, field) 
     if key_to_lower: 
      field = field.lower() 
     if isinstance(val, list): 
      data[field] = [] 
      for item in val: 
       data[field].append(sobject_to_dict(item, json_serialize=json_serialize)) 
     else: 
      data[field] = sobject_to_dict(val, json_serialize=json_serialize) 
    return data 


def sobject_to_json(obj, key_to_lower=False): 
    """ 
    Converts a suds object to json. 
    :param obj: suds object 
    :param key_to_lower: If set, changes index key name to lower case. 
    :return: json object 
    """ 
    import json 
    data = sobject_to_dict(obj, key_to_lower=key_to_lower, json_serialize=True) 
    return json.dumps(data) 

如果有一个更简单的方法,我很想听到它。

7

suds.client.Client类中有一个名为dict的类方法,它将sudsobject作为输入并返回Python dict作为输出。看看这里:Official Suds Documentation

产生的片段变得优雅,因为这:

from suds.client import Client 

# Code to obtain your suds_object here... 

required_dict = Client.dict(suds_object) 

你可能也想看看在提取从suds_object类似项目相同的类items类方法(linkitems方法dict

+0

现在我知道它是如何提取信息形式的python dic。 – Ayoub

0

checkaayush的答案不是递归的,所以它不考虑嵌套对象。

基于aGuegu回答我做了一些更改,以解决泡沫对象在列表中有dicts时的问题。

它的工作原理!


from suds.sudsobject import asdict 

def recursive_asdict(d): 
    """Convert Suds object into serializable format.""" 
    out = {} 
    for k, v in asdict(d).items(): 
     if hasattr(v, '__keylist__'): 
      out[k] = recursive_asdict(v) 
     elif isinstance(v, list): 
      out[k] = [] 
      for item in v: 
       if hasattr(item, '__keylist__'): 
        out[k].append(recursive_asdict(item)) 
       elif not isinstance(item, list): 
        out[k] = item 
       else: 
        out[k].append(item) 
     else: 
      out[k] = v 
    return out