Comment décaper un CookieJar?
-
06-07-2019 - |
Question
J'ai un objet avec un CookieJar que je veux mariner.
Cependant, comme vous le savez probablement tous, pickle Chokes sur des objets contenant des objets verrouillés. Et pour une raison horrible, un CookieJar a un objet de verrouillage.
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
Comment est-ce que je persiste?
La seule solution à laquelle je puisse penser consiste à utiliser FileCookieJar.save et FileCookieJar.load à un objet stringIO. Mais existe-t-il un meilleur moyen?
La solution
Voici une tentative, en dérivant une classe de CookieJar, qui annule la commande getstate / setstate utilisée par pickle. Je n'ai pas utilisé cookieJar, donc je ne sais pas s'il est utilisable, mais vous pouvez vider la classe dérivée
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)
Autres conseils
CookieJar
n'est pas particulièrement bien conçu pour la persistance (c'est en cela que servent principalement les sous-classes FileCookieJar
! -), mais vous pouvez effectuer une itération sur un CookieJar
instance pour obtenir tous les cookies (et conserver une liste de ceux-ci, par exemple) et, pour reconstruire le fichier jar avec les cookies, utilisez set_cookie
sur chacun. C’est ainsi que j’ai décidé de conserver ou de supprimer les pots de cookies en utilisant la méthode copy_reg
pour enregistrer les fonctions appropriées si j’avais besoin de les utiliser souvent.