1
2
3
4
5
6
7
8
9 """Helper for simple storage facility via cPickle and zlib"""
10
11 __docformat__ = 'restructuredtext'
12
13 import os
14
15 from mvpa.base import externals
16 externals.exists('cPickle', raiseException=True)
17 externals.exists('gzip', raiseException=True)
18
19 _d_geti_ = dict.__getitem__
20 _d_seti_ = dict.__setitem__
21
22 _o_geta_ = dict.__getattribute__
23 _o_seta_ = dict.__setattr__
24
25 import cPickle, gzip
26
27 if __debug__:
28 from mvpa.base import debug
29
31 """Simple container class with basic IO capabilities.
32
33 It is capable of storing itself in a file, or loading from a file
34 (using cPickle + zlib tandem). Any serializable object can be
35 bound to a hamster to be stored.
36
37 To undig burried hamster use Hamster(filename). Here is an example:
38
39 >>> h = Hamster(bla='blai')
40 >>> h.boo = N.arange(5)
41 >>> h.dump(filename)
42 ...
43 >>> h = Hamster(filename)
44
45 Since Hamster introduces methods `dump`, `asdict` and property
46 'registered', those names cannot be used to assign an attribute,
47 nor provided in among constructor arguments.
48 """
49
50 __ro_attr = set(object.__dict__.keys() +
51 ['dump', 'registered', 'asdict'])
52 """Attributes which come with being an object"""
53
55 if len(args) > 0:
56 if len(kwargs) > 0:
57 raise ValueError, \
58 "Do not mix positional and keyword arguments. " \
59 "Use a single positional argument -- filename, " \
60 "or any number of keyword arguments, without having " \
61 "filename specified"
62 if len(args) == 1 and isinstance(args[0], basestring):
63 filename = args[0]
64 args = args[1:]
65 if __debug__:
66 debug('IOH', 'Undigging hamster from %s' % filename)
67 f = gzip.open(filename)
68 result = cPickle.load(f)
69 if not isinstance(result, Hamster):
70 warning("Loaded other than Hamster class from %s" % filename)
71 return result
72 else:
73 raise ValueError, "Hamster accepts only a single positional " \
74 "argument and it must be a filename. Got %d " \
75 "arguments" % (len(args),)
76 else:
77 return object.__new__(cls)
78
79
81 """Initialize Hamster.
82
83 Providing a single parameter string would treat it as a
84 filename from which to undig the data. Otherwise all keyword
85 parameters are assigned into the attributes of the object.
86 """
87 if len(args) > 0:
88 if len(args) == 1 and isinstance(args[0], basestring):
89
90 args = args[1:]
91 else:
92 raise RuntimeError, "Should not get here"
93
94
95 for k,v in kwargs.iteritems():
96 setattr(self, k, v)
97
98 object.__init__(self)
99
100
101 - def dump(self, filename):
102 """Bury the hamster into the file
103 """
104 if __debug__:
105 debug('IOH', 'Burying hamster into %s' % filename)
106 f = gzip.open(filename, 'w')
107 cPickle.dump(self, f)
108 f.close()
109
110
112 reg_attr = ["%s=%s" % (k, repr(getattr(self, k)))
113 for k in self.registered]
114 return "%s(%s)" % (self.__class__.__name__,
115 ", ".join(reg_attr))
116
117
118
119
120
121
122
123
124
125 @property
127 """List registered attributes.
128 """
129 reg_attr = [k for k in self.__dict__.iterkeys()
130 if not k in self.__ro_attr]
131 reg_attr.sort()
132 return reg_attr
133
134
136 """Just to prevent resetting read-only attributes, such as methods
137 """
138 if k in self.__ro_attr:
139 raise ValueError, "'%s' object attribute '%s' is read-only" \
140 % (self.__class__.__name__, k)
141 object.__setattr__(self, k, v)
142
143
145 """Return registered data as dictionary
146 """
147 return dict([(k, getattr(self, k))
148 for k in self.registered])
149