【问题标题】:Python pickle seems to break inside class, but not in command line scriptPython pickle 似乎在类内部中断,但不在命令行脚本中
【发布时间】:2010-11-09 15:50:59
【问题描述】:

我一直在尝试从数据库中提取一些字典。我已经恢复使用 marshal 模块,但仍然想知道为什么 pickle 在反序列化某些数据时遇到这么困难。这是一个命令行 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)

【问题讨论】:

    标签: python django serialization django-models pickle


    【解决方案1】:

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

    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'}
    

    【讨论】:

    • 我正在使用 apache mod_wsgi 的 django 环境下运行它。也许那有什么问题?这真的很奇怪,因为上面的 shell 会话是在同一个 django 环境中完成的(python manage.py shell)。尝试从数据库进行查找时会出现问题(我正在使用 Resource 类来驱动 Django 中的一个特殊模型字段,该字段从序列化数据所在的 db 列中读取)。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-01-02
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      相关资源
      最近更新 更多