-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPickleList.py
More file actions
189 lines (143 loc) · 4.55 KB
/
PickleList.py
File metadata and controls
189 lines (143 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import os
import pickle
import shutil
class PickleList:
"""
The purpose of this class is to define a data structure that has an
interface very similar to that of a Python list. However, instead of
storing its items in RAM as in a normal python list, a pickle list
stores each of its items as separate pickle files. This is useful when
the items are too big to store them all at once in RAM.
"""
def __init__(self, base_dir):
"""
Constructor
Parameters
----------
base_dir: str
all items in the pickle list will be stored in a folder with
this name, and named "item0", "item1", "item2", ..., etc.
"""
self.base_dir = base_dir
self.index = 0
if os.path.exists(base_dir):
shutil.rmtree(base_dir)
os.makedirs(base_dir)
def restart(self):
"""
This method empties the base directory, but keeps the directory itself.
Returns
-------
None
"""
shutil.rmtree(self.base_dir)
os.makedirs(self.base_dir)
self.index = 0
def __len__(self):
"""
This method gives the number of items in the list, which is the same
as the number of pickle files in the base directory.
Returns
-------
int
"""
return self.index
def __getitem__(self, index):
"""
This method allows the user to access an item in a pickle list li by
using li[index] where index is a 0-based int within the range 0:len(
li).
Parameters
----------
index: int
Returns
-------
Any
"""
item_name = f'item{index}'
file_path = os.path.join(self.base_dir, item_name)
if not os.path.exists(file_path):
raise IndexError(f"Index {index} out of range")
with open(file_path, 'rb') as file:
item = pickle.load(file)
return item
def append(self, item):
"""
This method allows one to append items to the pickle list the same
way one does with a python list.
Parameters
----------
item: Any
Returns
-------
"""
item_name = f'item{self.index}'
file_path = os.path.join(self.base_dir, item_name)
with open(file_path, 'wb') as file:
pickle.dump(item, file)
self.index += 1
def __iter__(self):
"""
This method returns a ListIterator (i.e., an iterator for the pickle
list). This in turn allows statements like `for x in li:`,
where `li` is a pickle list.
Returns
-------
ListIterator
"""
return self.ListIterator(self.base_dir)
class ListIterator:
"""
This class creates an iterator for a pickle list. Objects of this
class should only be used internally by class PickleList. That is
why this class is declared inside class PickleList.
"""
def __init__(self, base_dir):
"""
Constructor
Parameters
----------
base_dir: str
"""
self.base_dir = base_dir
self.index = 0
def __iter__(self):
"""
This method returns self.
Returns
-------
ListIterator
"""
return self
def __next__(self):
"""
This method returns the next item in the pickle list. That item
is obtained by reading it from a pickle file.
Returns
-------
Any
"""
item_name = f'item{self.index}'
file_path = os.path.join(self.base_dir, item_name)
if not os.path.exists(file_path):
raise StopIteration
with open(file_path, 'rb') as file:
item = pickle.load(file)
# Delete the file after loading it
# os.remove(file_path)
self.index += 1
return item
if __name__ == "__main__":
def main():
base_dir = "example_PickleList_files"
plist = PickleList(base_dir)
# Appending items to the list and storing in separate pickle files
plist.append("Item 0")
plist.append("Item 1")
plist.append("Item 2")
print(plist[1])
print(len(plist))
# Iterating over the stored items, deleting the pickle files as we go
for item in plist:
print(item)
main()