如何将 CookieJar 进行序列化?

9
我有一个带有CookieJar的对象需要进行pickle。
然而,正如你们可能知道的那样,pickle会在包含锁对象的对象上出现问题。而且出于某种可怕的原因,CookieJar有一个锁对象。
from cPickle import dumps
from cookielib import CookieJar

class Person(object):
    def __init__(self, name):
        self.name = name
        self.cookies = CookieJar()

bob = Person("bob")
dumps(bob)

# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# cPickle.UnpickleableError: Cannot pickle <type 'thread.lock'> objects

如何持久化它?

我唯一想到的解决方案是使用FileCookieJar.save和FileCookieJar.load将其保存到一个stringIO对象中。但是否有更好的方法?


7
哇!这个问题听起来像是厨房工作的问题。我很惊讶这些工具所使用的名称 :) - shahkalpesh
你找到了好的解决方案吗?如果是,请发布。 - Paul Tarjan
1
@Paul,Alex和Anurag的解决方案都有效。虽然Anurag的解决方案有些取巧但速度更快,而Alex的解决方案则更通用但速度较慢,所以我将让社区决定哪个更好。 - Unknown
乍一看,我以为这是一个玩笑问题。 - Claudiu
2个回答

9

以下是一种尝试,通过从CookieJar中派生一个类并重写pickle所使用的getstate/setstate方法。我没有使用过CookieJar,因此不知道它是否可用,但您可以转储派生类。

from cPickle import dumps
from cookielib import CookieJar
import threading

class MyCookieJar(CookieJar):
    def __getstate__(self):
        state = self.__dict__.copy()
        del state['_cookies_lock']
        return state

    def __setstate__(self, state):
        self.__dict__ = state
        self._cookies_lock = threading.RLock()

class Person(object):
    def __init__(self, name):
        self.name = name
        self.cookies = MyCookieJar()

bob = Person("bob")
print dumps(bob)

缺点:它依赖于CookieJar的内部逻辑。 - Anurag Uniyal
1
优点:它简单而优雅! - Alex
1
对于“优雅”的某些定义 = P。我也喜欢这种方法。 - Claudiu

7

CookieJar 并不是为持久存储而设计的(这就是 FileCookieJar 的子类大部分实现的功能!-),但您可以迭代一个 CookieJar 实例来获取所有 cookie(并且例如持久保存该列表),并使用 set_cookie 在每个 cookie 上进行重建 jar。如果我经常需要使用它们,那么我会使用 copy_reg 方法注册适当的函数来持久化和取消持久化 cookie jars。


我认为这个答案比被接受的那个更好。也许使用pickling确实是他需要的,但这似乎相当不可能。FileCookieJar子类更简单、可靠、便携且开箱即用。 - rspeed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接