[Tutor] Saving class data to a text file

2005-07-16 Thread Darryl Luff
Hi all. I'm looking at Python for the first time, and using it for an
app I'm writing to try it out. I normally use c or perl.

I have a class that has half a dozen or so data fields. It needs to be
able to save its data to a text file, in a format that's easy to edit
with other tools (vi, perl, etc). And needs to be able to load itself
back from disk.

I discovered that a dictionary can convert itself into a nice string
format that I can save directly to a file. So I thought I could put a
dictionary in the class to hold the data, and save the string
representation of the dictionary to the file. Each object instance is on
a single text line. I created get/set methods for each field to avoid
problems if I mis-type the dictionary keys.

Now I have a couple of questions:
- What is the recommended 'python' way to implement this class? and
- If what I'm doing is OK, is there an easy way to load a dictionary
from the string representation without parsing the string manually?


Thanks for your time!

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Saving class data to a text file

2005-07-19 Thread Darryl Luff
Alan G wrote:

> ...

> Take a look at the OOP topic in my tutor. It includes an examnple
> of how to save/load objects to text files.

Thanks Alan, Javier and Jonathon. The answers I got all showed me bits
of Python I haven't seen before! I'll have to take a while to digest the
others.

I left another requirement out - the fields have to include their field
names. I've been caught with perl scripts when using CSV files, and
different scripts used different field orders...

So the format str(dictionary) gives is really just what I want. It's
line-oriented, and includes the field names. So for now I've stuck to
using that.
 

> ...

> The native python solution would be to use pickle or shelve modules.
> If it must be human friendly too then the approach in my tutor
> supplemented by overloading the __repr__() method would work.

I've overloaded __repr__ of the object to just return a str() of the
internal dictionary. Is this OK? Or is __repr__ used for something else
that I've now broken? So to save the object to a file I just write
repr(object) + "\n".

> ...
> You might try eval() but it is full of security implications, rogue
> code in your data could be evaluated and do who knows what kind of
> mischief...

I wasn't comfortable using eval() to retrieve the value, so I used a
regex to unpack it. I think I do like the perl builtin $variable =~
/regex/ syntax better than the re.compile()/match() stuff.

I'll include a stripped-down version of the object below. If anyone's
looking for something to do I'd appreciate any comments on more
'python'y ways to do it!

At a first look python looks OK. The indentation takes a bit of getting
used to, especially when copying scripts out of emails! It's easy to
space something wrong and have the script doing strange things!


Thanks.

=
import re

class Test:
  def __init__(self):
self.dat = {}

  def __repr__(self):
return str(self.dat)

  def GetName(self):
if self.dat.has_key('name'):
  return self.dat['name']
else:
  return ""

  def SetName(self, n):
self.dat['name'] = n

  def LoadFrom(self, line):
self.dat = {}
p = re.compile("'(.*?)'\s*:\s*('.*?'|\S+)\s*(.*)")
print "Checking " + line
m = p.search(line)
while m:
  print "Matched " + m.group(1) + " = " + m.group(2)
  val = m.group(2)
  val.strip("'")

  self.dat[m.group(1)] = val
  m = p.search(m.group(3))

  def ToString(self):
return str(self.dat)

filename = "/tmp/dat.txt"

test = Test()
test.SetName("Fred")
f = open(filename, "w")
f.write(repr(test) + "\n")
f.close()

test = Test()
print "Retrieved: " + test.GetName()
f = open(filename, "r")
test.LoadFrom(f.readline())
f.close()

print "Retrieved: " + test.GetName()

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor