我正在处理一些xml文件
pb_id
是一个字符串
page_elements
是一个列表。
pb_id = x.xpath('//pb/@xml:id')[0]
page_elements = x.xpath('//@xml:id[preceding::pb]')
我想将这些值保存在搁置缓存中:
s = shelve.open('cache.shelve')
s[str(pb_id)] = page_elements
但它会返回此错误:
无法挑选_Element对象
我是否需要将page_elements
转换为其他类型?
type(page_elements)
为<type 'list'>
答案 0 :(得分:1)
只有可选择的数据类型可以存储在一个架子中 - 特别是,C扩展添加的类型需要显式支持才能被选择;到目前为止,lxml还没有写过支持。
除非您愿意为上游lxml提供补丁并通过合并和发布来管理它,否则我建议您重新审视您的要求:为什么要尝试存储有问题的数据?您能否以不同的方式(例如,XML文本 - 即使该文本被搁置)序列化内容,并在加载时反序列化它?
如果将XML元素封装在您控制的数据结构中,则可以覆盖__getstate__()
和__setstate__()
以适当地序列化和反序列化;请阅读the pickle library documentation了解详情。
你最终可能会遇到这样的事情:
class PicklablePage(object):
def __init__(self, page_elements=None):
self.page_elements = page_elements or []
def __getstate__(self):
return {'page_elements': [ lxml.etree.tostring(el)
for el in self.page_elements ]}
def __setstate__(self, state):
self.page_elements = [ lxml.etree.fromstring(el_text)
for el_text in state['page_elements'] ]
然后可以安全地对其进行酸洗和去除(因此搁置和取消搁置):
>>> el = lxml.etree.fromstring('<content>Hello</content>')
>>> p = PicklablePage([el])
>>> print pickle.loads(pickle.dumps(p)).page_elements[0].text
Hello
答案 1 :(得分:1)
好的,明白了:列表是由_Element对象组成的。 我想我已经解决了这个问题,将所有列表元素转换为str()
page_elements[:] = [str(x) for x in page_elements]