在Python中反序列化'嵌套'数组

时间:2011-01-16 16:04:02

标签: python serialization

我一直在尝试反序列化进入我的python脚本的数组。我发现了Python的一些扩展(如Scott Hurring的版本:http://hurring.com/scott/code/python/serialize/),它可以简单地反序列化简单的数据结构,如:

a:2:{s:7:"version";s:3:"457";s:12:"version_beta";s:3:"461";};

我的数据看起来像这样(几个嵌套数组):

5:a:{i:17;s:2:"36";i:26;a:1:{i:0;s:2:"44";}i:18;s:0:"";i:24;s:0:"";i:19;a:1:{i:0;s:2:"40";}}s:3:"qty";s:1:"1";}s:7:"options";a:3:{i:0;a:7:{s:5:"label";s:13:"Build options";s:5:"value";s:35:"Place headset, leave fork untouched";s:11:"print_value";s:35:"Place headset, leave fork untouched";s:9:"option_id";s:2:"17";s:11:"option_type";s:5:"radio";s:12:"option_value";s:2:"36";s:11:"custom_view";b:0;}i:1;a:7:{s:5:"label";s:22:"Front derailleur mount";s:5:"value";s:33:"Frame with front derailleur mount";s:11:"print_value";s:33:"Frame with front derailleur mount";s:9:"option_id";s:2:"26";s:11:"option_type";s:8:"checkbox";s:12:"option_value";s:2:"44";s:11:"custom_view";b:0;}i:2;a:7:{s:5:"label";s:18:"Pre-order discount";s:5:"value";s:22:"10% pre-order discount";s:11:"print_value";s:22:"10% pre-order discount";s:9:"option_id";s:2:"19";s:11:"option_type";s:8:"checkbox";s:12:"option_value";s:2:"40";s:11:"custom_view";b:0;}}s:14:"bundle_options";a:2:{i:24;a:3:{s:9:"option_id";s:2:"24";s:5:"label";s:6:"Tiller";s:5:"value";a:1:{i:0;a:3:{s:5:"title";s:11:"Tiller 90";s:3:"qty";i:1;s:5:"price";d:0;}}}i:22;a:3:{s:9:"option_id";s:2:"22";s:5:"label";s:22:"Seat size and material";s:5:"value";a:1:{i:0;a:3:{s:5:"title";s:12:"Seat (large)";s:3:"qty";i:1;s:5:"price";d:0;}}}}s:20:"product_calculations";i:1;s:13:"shipment_type";s:1:"0";}

在PHP中,我可以简单地反序列化并获得几个嵌套数组:

    Array
(
    [info_buyRequest] => Array
        (
            [uenc] => aHR0cDovL3d3dy5yYXB0b2Jpa2UubmwvYmlrZXMvbWlkLXJhY2VyL21kaS1yYWNlci1mcmFtZS1raXQuaHRtbD9fX19TSUQ9VSZvcHRpb25zPWNhcnQ,
            [product] => 171
            [related_product] => 
            [bundle_option] => Array
                (
                    [22] => 69
                    [24] => 74
                )

            [options] => Array
                (
                    [17] => 36
                    [26] => Array
                        (
                            [0] => 44
                        )

                    [18] => 
                    [24] => 
                    [19] => Array
                        (
                            [0] => 40
                        )

                )

            [qty] => 1
        )

    [options] => Array
        (
            [0] => Array
                (
                    [label] => Build options
                    [value] => Place headset, leave fork untouched
                    [print_value] => Place headset, leave fork untouched
                    [option_id] => 17
                    [option_type] => radio
                    [option_value] => 36
                    [custom_view] => 
                )

            [1] => Array
                (
                    [label] => Front derailleur mount
                    [value] => Frame with front derailleur mount
                    [print_value] => Frame with front derailleur mount
                    [option_id] => 26
                    [option_type] => checkbox
                    [option_value] => 44
                    [custom_view] => 
                )

            [2] => Array
                (
                    [label] => Pre-order discount
                    [value] => 10% pre-order discount
                    [print_value] => 10% pre-order discount
                    [option_id] => 19
                    [option_type] => checkbox
                    [option_value] => 40
                    [custom_view] => 
                )

        )

    [bundle_options] => Array
        (
            [24] => Array
                (
                    [option_id] => 24
                    [label] => Tiller
                    [value] => Array
                        (
                            [0] => Array
                                (
                                    [title] => Tiller 90°
                                    [qty] => 1
                                    [price] => 0
                                )

                        )

                )

            [22] => Array
                (
                    [option_id] => 22
                    [label] => Seat size and material
                    [value] => Array
                        (
                            [0] => Array
                                (
                                    [title] => Seat (large)
                                    [qty] => 1
                                    [price] => 0
                                )

                        )

                )

        )

    [product_calculations] => 1
    [shipment_type] => 0
)

但是我无法弄清楚如何在Python中获得这个或类似的结构?

感谢你帮助建议json和pickle。我试过这些并得到奇怪的错误。

如果我使用这个小脚本:

import pickle
import json

data = 'a:2:{s:7:"version";s:3:"457";s:12:"version_beta";s:3:"461";};'

my_array = json.loads(data)

print my_array

然后我得到:

File "unser.py", line 8, in <module>
  my_array = json.loads(data)
File "/usr/lib/python2.6/json/__init__.py", line 307, in loads
  return _default_decoder.decode(s)
File "/usr/lib/python2.6/json/decoder.py", line 319, in decode
  obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.6/json/decoder.py", line 338, in raw_decode
  raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

如果我将json.loads换成pickle.loads,我会:

Traceback (most recent call last):
File "unser.py", line 8, in <module>
  my_array = pickle.loads(data)
File "/usr/lib/python2.6/pickle.py", line 1374, in loads
  return Unpickler(file).load()
File "/usr/lib/python2.6/pickle.py", line 858, in load
  dispatch[key](self)
File "/usr/lib/python2.6/pickle.py", line 1180, in load_append
  value = stack.pop()
IndexError: pop from empty list

我显然在这里错过了一些愚蠢的东西......

2 个答案:

答案 0 :(得分:3)

stdlib中有一个序列化模块,名为pickle

  

pickle模块实现了一个基本但强大的算法,用于序列化和反序列化Python对象结构。 “Pickling”是将Python对象层次结构转换为字节流的过程,“unpickling”是反向操作,从而将字节流转换回对象层次结构。

>>> # example for serializing a dict into a file ...
>>> import pickle
>>> pickle.dump({"Hello" : ["World", "Moon"]}, open("/tmp/test.pkl", "wb"))
>>> pickle.load(open("/tmp/test.pkl", "rb"))
{'Hello': ['World', 'Moon']}

此外,由于Python 2.6在stdlib中有一个json module,它可以用作轻量级数据交换格式

答案 1 :(得分:0)

我找到了解决方案。我现在正在使用一个正常工作的模块phpserialize(http://pypi.python.org/pypi/phpserialize)。事实证明我的原始传入数据中包含非UTF字符,所以我必须先转换。

lleto