开发者

Unserialize 'nested' arrays in Python

I've been trying to unserialize an array coming into my python script. I have found some extensions to Python (like Scott Hurring's version: http://hurring.com/scott/code/python/serialize/) that unserialize simple data structures like:

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

My data looks like this (couple of nested arrays):

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";}

In PHP I can simply unserialize this and get a couple of nested array's:

    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
                (
                    [lab开发者_高级运维el] => 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
)

However I can't figure out how to get this or a similar structure in Python?

Thanks for the help in suggesting json and pickle. I had tried these and get strange errors.

If I use this little script:

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

Then I get:

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

If I swap json.loads for pickle.loads I get:

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

I'm obviously missing something silly here...


There is a module for serialization in the stdlib, called pickle.

The pickle module implements a fundamental, but powerful algorithm for serializing and de-serializing a Python object structure. “Pickling” is the process whereby a Python object hierarchy is converted into a byte stream, and “unpickling” is the inverse operation, whereby a byte stream is converted back into an object hierarchy.

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

Also, since Python 2.6 there is a json module in the stdlib, which can be used as a lightweight data interchange format.


well I've found the solution. I'm now using a module phpserialize (http://pypi.python.org/pypi/phpserialize) which is working fine. It turned out that my original incoming data had non UTF characters in it, so I had to convert first.

lleto

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜