2010-11-09 37 views
2

我一直在尝试unickle从数据库中的一些字典。我已经恢复使用编组模块,但仍然想知道为什么pickle在反序列化某些数据时遇到了这么困难的时刻。下面是一个命令行的Python会话的表现基本上就是我想要做的事:Python泡菜似乎打破课堂内部,但不是在命令行脚本

>>> a = {'service': 'amazon', 'protocol': 'stream', 'key': 'lajdfoau09424jojf.flv'} 
>>> import pickle; import base64 
>>> pickled = base64.b64encode(pickle.dumps(a)) 
>>> pickled 
'KGRwMApTJ3Byb3RvY29sJwpwMQpTJ3N0cmVhbScKcDIKc1Mna2V5JwpwMwpTJ2xhamRmb2F1MDk0MjRqb2pmLmZsdicKcDQKc1Mnc2VydmljZScKcDUKUydhbWF6b24nCnA2CnMu' 
>>> unpickled = pickle.loads(base64.b64decode(pickled)) 
>>> unpickled 
{'protocol': 'stream', 'service': 'amazon', 'key': 'lajdfoau09424jojf.flv'} 
>>> unpickled['service'] 
'amazon' 

这工作都很好,但是当我尝试这样的一类工厂方法里面,它似乎像pickle.loads部分出错。我尝试加载的字符串与上面相同。我甚至试图复制在上面的命令行会话中腌制的确切字符串,并试图解除这个问题,但没有成功。以下是此后尝试的代码:

class Resource: 

    _service = 'unknown' 
    _protocol = 'unknown' 
    _key = 'unknown' 

    ''' 
    Factory method that creates an appropriate instance of one of Resource’s subclasses based on 
    the type of data provided (the data being a serialized dictionary with at least the keys 'service', 
    'protocol', and 'key'). 
    @param resource_data (string) -- the data used to create the new Resource instance. 
    ''' 
    @staticmethod 
    def resource_factory(resource_data): 
     # Unpack the raw resource data and then create the appropriate Resource instance and return. 
     resource_data = "KGRwMApTJ3Byb3RvY29sJwpwMQpTJ3N0cmVhbScKcDIKc1Mna2V5JwpwMwpTJ2xhamRmb2F1MDk0MjRqb2pmLmZsdicKcDQKc1Mnc2VydmljZScKcDUKUydhbWF6b24nCnA2CnMu" #hack to just see if we can unpickle this string 
     logging.debug("Creating resource: " + resource_data) 
     unencoded = base64.b64decode(resource_data) 
     logging.debug("Unencoded is: " + unencoded) 
     unpacked = pickle.loads(unencoded) 
     logging.debug("Unpacked: " + unpacked) 
     service = unpacked['service'] 
     protocol = unpacked['protocol'] 
     key = unpacked['key'] 

     if (service == 'amazon'): 
      return AmazonResource(service=service, protocol=protocol, key=key) 
     elif (service == 'fs'): 
      return FSResource(service=service, protocol=protocol, key=key) 

回答

0

我能够做一些简化,然后在Django调试后,解决这个问题。主要问题是Resource类本身存在一些错误,这些错误阻止了resource_factory方法的正确完成。首先,我试图连接一个字符串和字典,这是一个错误。我在课程的其他地方也遇到了一些错误,我指的是实例变量_service,_protocol和,而没有''(拼写错误)。

在任何情况下,有趣的是,当我在Django的自定义字段基础结构中使用此代码时,错误将被捕获,并且我没有看到任何指示问题的实际消息。调试语句表明它是一个加载问题,但实际上它是调试语句本身和稍后出现的一些代码的问题。当我尝试使用模型属性而不是自定义模型字段为我保存的数据实现此行为时,实际上错误已经打印出来,我能够快速调试。

0

您的代码有效。你如何测试它?

import logging 
import base64 
import pickle 
class Resource: 
    @staticmethod 
    def resource_factory(resource_data): 
     resource_data = "KGRwMApTJ3Byb3RvY29sJwpwMQpTJ3N0cmVhbScKcDIKc1Mna2V5JwpwMwpTJ2xhamRmb2F1MDk0MjRqb2pmLmZsdicKcDQKc1Mnc2VydmljZScKcDUKUydhbWF6b24nCnA2CnMu" #hack to just see if we can unpickle this string 
     # logging.debug("Creating resource: " + resource_data) 
     unencoded = base64.b64decode(resource_data) 
     # logging.debug("Unencoded is: " + unencoded) 
     unpacked = pickle.loads(unencoded) 
     logging.debug("Unpacked: " + repr(unpacked)) 
     service = unpacked['service'] 
     protocol = unpacked['protocol'] 
     key = unpacked['key'] 

logging.basicConfig(level=logging.DEBUG) 
Resource.resource_factory('') 

产生

# DEBUG:root:Unpacked: {'protocol': 'stream', 'service': 'amazon', 'key': 'lajdfoau09424jojf.flv'} 
+0

我正在使用apache mod_wsgi在django环境下运行它。那么也许有一些问题呢?这很奇怪,因为上面的shell会话是在相同的django环境(python manage.py shell)中完成的。尝试从数据库执行查找时会出现问题(我使用Resource类驱动Django中的特殊模型字段,该字段从序列化数据所在的数据库列中读取)。 – Faisal 2010-11-09 17:00:05

相关问题