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

0 投票
2 回答
1954 浏览
提问于 2025-04-16 10:03

我一直在尝试将一个数组从我的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

我找到了问题的解决办法。现在我在用一个叫做 phpserialize 的模块(http://pypi.python.org/pypi/phpserialize),效果很好。原来我最开始接收到的数据里面有一些不是 UTF 编码的字符,所以我得先把这些字符转换一下。

lleto

2

在Python的标准库里,有一个叫做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开始,标准库里还有一个json模块,可以用作一种轻量级的数据交换格式

撰写回答