[英]Parsing Suds SOAP complex data type into Python dict
我有一些數據來自使用Suds
的SOAP
API,我需要在我的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"
},
}
suds.client.Client
類中有一個名為dict
的類方法,它以sudsobject
作為輸入並返回 Python dict
作為輸出。 在這里查看: 官方 Suds 文檔
結果片段變得如此優雅:
from suds.client import Client
# Code to obtain your suds_object here...
required_dict = Client.dict(suds_object)
您可能還想查看同一個類中的items
類方法( 鏈接),它從 suds_object 中提取類似於dict
上的items
方法的items
。
您可以將對象dict()
為dict()
,但您仍然會獲得 suds 使用的復雜數據類型。 所以這里有一些我專門為這個場合寫的有用的函數:
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))
elif isinstance(val, (datetime.datetime, datetime.time, datetime.date)):
data[field] = val.isoformat()
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)
如果有更簡單的方法,我很想聽聽。
找到了一個解決方案:
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))
如果 subs 只是嵌套的 dict 和 list,它應該可以工作。
通常情況下,正確答案 在 docs 中。 (括號)中的位是可以包含其他對象或類型的對象。
在本例中,我們有一個ArrayOfBalance
對象,其中包含一個Balance
類型列表,每個類型都具有Amount
和Currency
屬性。
這些都可以使用.
符號,所以下面的單行代碼可以解決問題。
balance = {item.Currency: item.Amount for item in response.Balance}
我遇到了類似的問題,不得不閱讀 suds 回復。 Suds 響應將作為由對象組成的元組返回。 len(response) 將顯示 suds 響應元組中包含的對象數量。 為了訪問第一個對象,我們需要給出response[0]
。
在 IDLE 中,如果您鍵入>>>print response[0]
后跟一個句點“.” 符號,您將看到一個彈出窗口,顯示可以從此級別訪問的各種對象。
示例:如果您輸入response[0]
。 它將帶來一個彈出窗口並顯示 Balance 對象,因此命令現在將變為response[0].Balance
。
您可以按照相同的方法獲取后續級別下的對象列表
checkaayush 的答案不是遞歸的,所以它不考慮嵌套對象。
基於 aGuegu 答案,當 suds 對象在列表中有 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.