只有picklable数据类型可以存储在一个架子 - 特别是,由C扩展添加类型需要明确的支持是picklable;迄今为止,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'] ]
这可以被封装和拆封(因此搁置和unshelved)安全:
>>> el = lxml.etree.fromstring('<content>Hello</content>')
>>> p = PicklablePage([el])
>>> print pickle.loads(pickle.dumps(p)).page_elements[0].text
Hello
问题不在于名单,这是_Element对象。而且它们是一个基于C的扩展类型,因此您不能使用它们。而且Python不知道“铸造”。你可以做的是例如确定作为来自根的儿童的一系列索引的单个元素的实际路径,并腌制它。 – deets 2015-02-09 16:32:25