jef*_*fff 15 python soap pickle suds
好吧我正在努力改进python,所以我不确定这是开始我正在做什么的正确方法,但这是我目前的问题......
我需要通过SOAP方法获取一些信息,现在只使用部分信息,但存储整个结果以备将来使用(我们需要尽可能少地使用该服务).查找访问服务的最佳方式我认为suds是要走的路,它很简单,就像一个魅力来获取数据.但是现在我想以某种方式保存结果,最好是序列化/在数据库中,这样我以后可以把它拉出来并使用它.
什么是最好的方法,看起来像pickle/json不是一个选项?谢谢!
更新 阅读最佳答案我怎样才能腌泡沫效果?让我更好地了解为什么这不是一个选项,我想我已经卡住了重建一个基本的对象w /我需要的信息?
pla*_*aes 32
我一直在使用以下方法将Suds对象转换为JSON:
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))
Run Code Online (Sandbox Code Playgroud)
是的,我确认了你在你提到的答案中给出的解释 - 动态生成的类不容易被选择(也不容易序列化),你需要提取所有的状态信息,腌制那个状态,并在检索时重建棘手的sudsobject如果你真的坚持使用它;-).
这是我在研究和找到这个答案之前想到的。这实际上对我来说对复杂的泡沫响应以及其他对象都很有效,例如__builtins__因为解决方案与泡沫无关:
import datetime
def object_to_dict(obj):
if isinstance(obj, (str, unicode, bool, int, long, float, datetime.datetime, datetime.date, datetime.time)):
return obj
data_dict = {}
try:
all_keys = obj.__dict__.keys() # vars(obj).keys()
except AttributeError:
return obj
fields = [k for k in all_keys if not k.startswith('_')]
for field in fields:
val = getattr(obj, field)
if isinstance(val, (list, tuple)):
data_dict[field] = []
for item in val:
data_dict[field].append(object_to_dict(item))
else:
data_dict[field] = object_to_dict(val)
return data_dict
Run Code Online (Sandbox Code Playgroud)
此解决方案有效并且实际上更快。它也适用于没有该__keylist__属性的对象。
我在一个复杂的 suds 输出对象上运行了 100 次基准测试,这个解决方案的运行时间为 0.04 到 0.052 秒(平均为 0.045724287)。虽然recursive_asdict上述解决方案在 0.082 到 0.102 秒内运行,但几乎翻了一番(平均 0.0829765582)。
然后我回到绘图板并重新执行该功能以从中获得更多性能,并且不需要datetime导入。我利用了该__keylist__属性,因此这不适用于其他对象,例如__builtins__但对 suds 对象输出效果很好:
def fastest_object_to_dict(obj):
if not hasattr(obj, '__keylist__'):
return obj
data = {}
fields = obj.__keylist__
for field in fields:
val = getattr(obj, field)
if isinstance(val, list): # tuple not used
data[field] = []
for item in val:
data[field].append(fastest_object_to_dict(item))
else:
data[field] = fastest_object_to_dict(val)
return data
Run Code Online (Sandbox Code Playgroud)
运行时间为 0.18 - 0.033 秒(平均值为 0.0260889721),因此比recursive_asdict解决方案快近 4 倍。
小智 5
我为suds的Object intance做了一个虚拟类的实现,然后能够序列化.FakeSudsInstance的行为类似于原始的Suds Object实例,如下所示:
from suds.sudsobject import Object as SudsObject
class FakeSudsNode(SudsObject):
def __init__(self, data):
SudsObject.__init__(self)
self.__keylist__ = data.keys()
for key, value in data.items():
if isinstance(value, dict):
setattr(self, key, FakeSudsNode(value))
elif isinstance(value, list):
l = []
for v in value:
if isinstance(v, list) or isinstance(v, dict):
l.append(FakeSudsNode(v))
else:
l.append(v)
setattr(self, key, l)
else:
setattr(self, key, value)
class FakeSudsInstance(SudsObject):
def __init__(self, data):
SudsObject.__init__(self)
self.__keylist__ = data.keys()
for key, value in data.items():
if isinstance(value, dict):
setattr(self, key, FakeSudsNode(value))
else:
setattr(self, key, value)
@classmethod
def build_instance(cls, instance):
suds_data = {}
def node_to_dict(node, node_data):
if hasattr(node, '__keylist__'):
keys = node.__keylist__
for key in keys:
if isinstance(node[key], list):
lkey = key.replace('[]', '')
node_data[lkey] = node_to_dict(node[key], [])
elif hasattr(node[key], '__keylist__'):
node_data[key] = node_to_dict(node[key], {})
else:
if isinstance(node_data, list):
node_data.append(node[key])
else:
node_data[key] = node[key]
return node_data
else:
if isinstance(node, list):
for lnode in node:
node_data.append(node_to_dict(lnode, {}))
return node_data
else:
return node
node_to_dict(instance, suds_data)
return cls(suds_data)
Run Code Online (Sandbox Code Playgroud)
现在,在suds电话之后,例如下面:
# Now, after a suds call, for example below
>>> import cPickle as pickle
>>> suds_intance = client.service.SomeCall(account, param)
>>> fake_suds = FakeSudsInstance.build_instance(suds_intance)
>>> dumped = pickle.dumps(fake_suds)
>>> loaded = pickle.loads(dumped)
Run Code Online (Sandbox Code Playgroud)
我希望它有所帮助.
| 归档时间: |
|
| 查看次数: |
12432 次 |
| 最近记录: |