在搁置中保存 lxml 元素时出现类型错误
type error saving lxml elements in shelve
我正在处理一些 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
但是它returns这个错误:
can't pickle _Element objects
我需要将 page_elements
转换为其他类型吗?
type(page_elements)
是 <type 'list'>
只能将可挑选的数据类型存储在架子中——特别是,由 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'] ]
然后可以安全地 pickle 和 unpickled(因此搁置和取消搁置):
>>> el = lxml.etree.fromstring('<content>Hello</content>')
>>> p = PicklablePage([el])
>>> print pickle.loads(pickle.dumps(p)).page_elements[0].text
Hello
ok,明白了:list是由_Element对象构成的。
我想我已经通过这种方式解决了,将所有列表元素转换为 str()
page_elements[:] = [str(x) for x in page_elements]
我正在处理一些 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
但是它returns这个错误:
can't pickle _Element objects
我需要将 page_elements
转换为其他类型吗?
type(page_elements)
是 <type 'list'>
只能将可挑选的数据类型存储在架子中——特别是,由 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'] ]
然后可以安全地 pickle 和 unpickled(因此搁置和取消搁置):
>>> el = lxml.etree.fromstring('<content>Hello</content>')
>>> p = PicklablePage([el])
>>> print pickle.loads(pickle.dumps(p)).page_elements[0].text
Hello
ok,明白了:list是由_Element对象构成的。 我想我已经通过这种方式解决了,将所有列表元素转换为 str()
page_elements[:] = [str(x) for x in page_elements]