Object "dumping"

Derek Thomson dthomson at NOSPAMusers.sf.net
Mon Feb 3 04:25:30 EST 2003


Hi Andrew,

Andrew Bennetts wrote:
 > On Mon, Feb 03, 2003 at 11:47:38AM +1000, Derek Thomson wrote:
 >>
 >>I know Python has pprint, but that stops when it encounters an object
 >>ie. it only dumps sequences and hashes, which is less than what I want.
 >
 >
 > The problem is harder than it seems... simply recursively printing the
 > objects and their contents won't work for cyclic objects, so for many data
 > structures, you *need* something that can cope with this, like pickle.

No, I'm aware of this issue. Perl's Data::Dumper just deals with it :)

 >
 > So, if you simply want to dump the objects to a file, and read them back in,
 > and don't care about human-readability, use pickle.

Since I need this for debugging, I need to read it. Data::Dumper must be
one of my favourite modules. Problems just melt away when you can write
out the contents of an object at any point, or from the debugger command
line. I really think Python should have an equivalent!

Here's an example of how it handles recursion. It's more Perl, but bear
with me as it's quite cool.

Okay, say you did this in the last example:

#!/usr/bin/env perl

use warnings;
use strict;
use English;

use RequestHeader;

use Data::Dumper;

my $rh1 = RequestHeader->new('some context', 13, 1,
                              'an object key', 'op1name',
                              undef);

my $rh2 = RequestHeader->new('some other context', 14, 2,
                              'different object key', 'op2name',
                              undef);

my $rh3 = RequestHeader->new('some other context', 14, 2,
                              'different object key', 'op2name',
                              [ $rh1, $rh2 ]);

$rh1->{principal} = $rh2;
$rh2->{principal} = $rh3;

print Dumper($rh1);

So the $rh1 points to $rh2, and $rh3 points back to $rh1 *and* $rh2.

The result is (excuse the long lines):

$VAR1 = bless( {
                  'requesting_principal' => undef,
                  'object_key' => 'an object key',
                  'service_context' => 'some context',
                  'principal' => bless( {
                                          'requesting_principal' => undef,
                                          'object_key' => 'different object key',
                                          'service_context' => 'some other context',
                                          'principal' => bless( {
                                                                  'requesting_principal' => [
                                                                                              $VAR1,
                                                                                              $VAR1->{'principal'}
                                                                                            ],
                                                                  'object_key' => 'different object key',
                                                                  'service_context' => 'some other context',
                                                                  'response_expected' => 2,
                                                                  'operation' => 'op2name',
                                                                  'request_id' => 14
                                                                }, 'RequestHeader' ),
                                          'response_expected' => 2,
                                          'operation' => 'op2name',
                                          'request_id' => 14
                                        }, 'RequestHeader' ),
                  'response_expected' => 1,
                  'operation' => 'op1name',
                  'request_id' => 13
                }, 'RequestHeader' );


Notice how it uses the $VAR variable name to refer back into itself to
unambiguously resolve the dependency. And the best part is that entire dump
is valid Perl, so you can just evaluate it to recreate the object structure!

 >
 > If you want to read it too, I'd recommend twisted.spread.jelly, from
 > Twisted.  It's an s-expression based serialisation format that essentially
 > does the same job as pickle, but is human readable -- particularly if you
 > run it through pprint <wink>.  I've used it a couple of times for debugging.
 >
 > There are other pickle alternatives too, like an XMLPickle, iirc.

Yes, but I need human readable, not XML! :)

I guess twisted.spread.jelly is an option, but I'd prefer it if the output
were just Python - then there's no need to learn a new notation.

Anyway, thanks heaps.

--
Derek.






More information about the Python-list mailing list