可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is there a Python module that can be used in the same way as Perl's Data::Dumper
module?
Edit: Sorry, I should have been clearer. I was mainly after a module for inspecting data rather than persisting.
BTW Thanks for the answers. This is one awesome site!
回答1:
Data::Dumper has two main uses: data persistence and debugging/inspecting objects. As far as I know, there isn't anything that's going to work exactly the same as Data::Dumper.
I use pickle for data persistence.
I use pprint to visually inspect my objects / debug.
回答2:
Possibly a couple of alternatives: pickle, marshal, shelve.
回答3:
I think the closest you will find is the pprint module.
>>> l = [1, 2, 3, 4]
>>> l.append(l)
>>> d = {1: l, 2: 'this is a string'}
>>> print d
{1: [1, 2, 3, 4, [...]], 2: 'this is a string'}
>>> pprint.pprint(d)
{1: [1, 2, 3, 4, <Recursion on list with id=47898714920216>],
2: 'this is a string'}
回答4:
For serialization, there are many options.
One of the best is JSON, which is a language-agnostic standard for serialization. It is available in 2.6 in the stdlib json
module and before that with the same API in the third-party simplejson
module.
You do not want to use marshal
, which is fairly low-level. If you wanted what it provides, you would use pickle.
I avoid using pickle the format is Python-only and insecure. Deserializing using pickle can execute arbitrary code.
- If you did use
pickle
, you want to use the C implementation thereof. (Do import cPickle as pickle
.)
For debugging, you usually want to look at the object's repr
or to use the pprint
module.
回答5:
Here is a simple solution for dumping nested data made up of dictionaries, lists, or tuples (it works quite well for me):
def printStruct(struc, indent=0):
if isinstance(struc, dict):
print ' '*indent+'{'
for key,val in struc.iteritems():
if isinstance(val, (dict, list, tuple)):
print ' '*(indent+1) + str(key) + '=> '
printStruct(val, indent+2)
else:
print ' '*(indent+1) + str(key) + '=> ' + str(val)
print ' '*indent+'}'
elif isinstance(struc, list):
print ' '*indent + '['
for item in struc:
printStruct(item, indent+1)
print ' '*indent + ']'
elif isinstance(struc, tuple):
print ' '*indent + '('
for item in struc:
printStruct(item, indent+1)
print ' '*indent + ')'
else: print ' '*indent + str(struc)
See it at work:
>>> d = [{'a1':1, 'a2':2, 'a3':3}, [1,2,3], [{'b1':1, 'b2':2}, {'c1':1}], 'd1', 'd2', 'd3']
>>> printStruct(d)
[
{
a1=> 1
a3=> 3
a2=> 2
}
[
1
2
3
]
[
{
b1=> 1
b2=> 2
}
{
c1=> 1
}
]
d1
d2
d3
]
回答6:
I too have been using Data::Dumper for quite some time and have gotten used to its way of displaying nicely formatted complex data structures. pprint as mentioned above does a pretty decent job, but I didn't quite like its formatting style. That plus pprint doesn't allow you to inspect objects like Data::Dumper does:
Searched on the net and came across these:
https://gist.github.com/1071857#file_dumper.pyamazon
>>> y = { 1: [1,2,3], 2: [{'a':1},{'b':2}]}
>>> pp = pprint.PrettyPrinter(indent = 4)
>>> pp.pprint(y)
{ 1: [1, 2, 3], 2: [{ 'a': 1}, { 'b': 2}]}
>>> print(Dumper.dump(y)) # Dumper is the python module in the above link
{
1: [
1
2
3
]
2: [
{
'a': 1
}
{
'b': 2
}
]
}
>>> print(Dumper.dump(pp))
instance::pprint.PrettyPrinter
__dict__ :: {
'_depth': None
'_stream': file:: >
'_width': 80
'_indent_per_level': 4
}
Also worth checking is http://salmon-protocol.googlecode.com/svn-history/r24/trunk/salmon-playground/dumper.py It has its own style and seems useful too.
回答7:
As far as inspecting your object goes, I found this a useful equivalent of Data:Dumper:
https://salmon-protocol.googlecode.com/svn-history/r24/trunk/salmon-playground/dumper.py
It can handle unicode strings.
回答8:
If you want something that works better than pprint, but doesn't require rolling your own, try importing dumper from pypi:
https://github.com/jric/Dumper.py or
https://github.com/ericholscher/pypi/blob/master/dumper.py
回答9:
I needed to return Perl-like dump for API request so I came up with this which doesn't format the output to be pretty, but makes perfect job for me.
from decimal import Decimal
from datetime import datetime, date
def dump(self, obj):
if obj is None:
return "undef"
if isinstance(obj, dict):
return self.dump_dict(obj)
if isinstance(obj, (list, tuple)):
return self.dump_list(obj)
if isinstance(obj, Decimal):
return "'{:.05f}'".format(obj)
# ... or handle it your way
if isinstance(obj, (datetime, date)):
return "'{}'".format(obj.isoformat(
sep=' ',
timespec='milliseconds'))
# ... or handle it your way
return "'{}'".format(obj)
def dump_dict(self, obj):
result = []
for key, val in obj.items():
result.append(' => '.join((self.dump(key), self.dump(val))))
return ' '.join(('{', ', '.join(result), '}'))
def dump_list(self, obj):
result = []
for val in obj:
result.append(self.dump(val))
return ' '.join(('[', ', '.join(result), ']'))
Using the above:
example_dict = {'a': 'example1', 'b': 'example2', 'c': [1, 2, 3, 'asd'], 'd': [{'g': 'something1', 'e': 'something2'}, {'z': 'something1'}]}
print(dump(example_dict))
will ouput:
{ 'b' => 'example2', 'a' => 'example1', 'd' => [ { 'g' => 'something1', 'e' => 'something2' }, { 'z' => 'something1' } ], 'c' => [ '1', '2', '3', 'asd' ] }