jd.
jd.

Reputation: 4773

Python: how to write a data struct to a file as text (not pickled)

Is there a way to write python data structs to a file as text.

e.g. an app is running and has a variable/object: OPTIONS = ('ON', 'OFF', )

I need to write/merge the OPTIONS tuple into another file, not as a pickled object, but as text, verbatim: OPTIONS = ('ON', 'OFF', )

I could traverse the tuple, and one by one write the elements into the target file, but was wondering if there's an easier way.

note: if i do a "straight" write, i get the following:

fout.write(OPTIONS)
 ... 
TypeError: argument 1 must be string or read-only character buffer, not tuple

Upvotes: 2

Views: 3655

Answers (3)

Etienne
Etienne

Reputation: 12590

I don't know your scope but you could use another serialisation/persistence system like JSON, or Twisted Jelly that are more human readable (there's others like YAML).

I used jelly in some project for preferences files. It's really easy to use but you have to use repr() to save the data in human readable form and then eval() to read it back. So don't do that on everything because there's a security risk by using eval().

Here's a code example that prettify the representation (add indentation):

VERSION = 'v1.1'

def read_data(filename):
    return unjelly(eval(open(filename, 'r').read().replace('\n', '').replace('\t', '')))

def write_data(filename, obj):
    dump = repr(jelly(obj))
    level = 0
    nice_dump = ['%s\n' % VERSION]
    for char in dump:
        if char == '[':
            if level > 0:
                nice_dump.append('\n' + '\t' * level)
            level += 1
        elif char == ']':
            level -= 1
        nice_dump.append(char)
    open(filename, 'w').write(''.join(nice_dump))

Upvotes: 1

Alex Martelli
Alex Martelli

Reputation: 881863

fout.write(str(OPTIONS)) does what you want in this case, but no doubt in many others it won't; repr instead of str may be closer to your desires (but then again it might not be, as you express them so vaguely and generally, beyond that single example).

Upvotes: 1

Tarnay Kálmán
Tarnay Kálmán

Reputation: 7066

You could use repr (repr works well with things that have a __repr__() method):

>>> OPTIONS=('ON', 'OFF', )
>>> "OPTIONS="+repr(OPTIONS)
"OPTIONS=('ON', 'OFF')"

Upvotes: 4

Related Questions