Skip to content

Commit c746f90

Browse files
author
Bane
committed
添加所有的Programming_in_Python3随书实例
1 parent 0348d00 commit c746f90

156 files changed

Lines changed: 38321 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2008-11 Qtrac Ltd. All rights reserved.
3+
# This program or module is free software: you can redistribute it and/or
4+
# modify it under the terms of the GNU General Public License as published
5+
# by the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version. It is provided for educational
7+
# purposes and is distributed in the hope that it will be useful, but
8+
# WITHOUT ANY WARRANTY; without even the implied warranty of
9+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
# General Public License for more details.
11+
12+
"""
13+
>>> u = Stack()
14+
>>> u.push(1); u.push(2); u.push(4)
15+
>>> str(u)
16+
'[1, 2, 4]'
17+
>>> u.can_undo
18+
True
19+
>>> while u.can_undo:
20+
... u.undo()
21+
>>> str(u)
22+
'[]'
23+
>>> for x in list(range(-5, 0)) + list(range(5)):
24+
... u.push(x)
25+
>>> str(u)
26+
'[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]'
27+
>>> u.top()
28+
4
29+
>>> total = 0
30+
>>> for x in range(5):
31+
... total += u.pop()
32+
>>> str(u), total
33+
('[-5, -4, -3, -2, -1]', 10)
34+
>>> while u.can_undo:
35+
... u.undo()
36+
>>> str(u)
37+
'[]'
38+
39+
>>> import os
40+
>>> import tempfile
41+
>>> filename = os.path.join(tempfile.gettempdir(), "fs.pkl")
42+
>>> fs = FileStack(filename)
43+
>>> for x in list(range(-5, 0)) + list(range(5)):
44+
... fs.push(x)
45+
>>> str(fs)
46+
'[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]'
47+
>>> fs.top()
48+
4
49+
>>> total = 0
50+
>>> for x in range(5):
51+
... total += fs.pop()
52+
>>> str(fs), total
53+
('[-5, -4, -3, -2, -1]', 10)
54+
>>> fs.push(909)
55+
>>> str(fs)
56+
'[-5, -4, -3, -2, -1, 909]'
57+
>>> os.path.basename(fs.filename)
58+
'fs.pkl'
59+
>>> fs.save()
60+
>>> fs2 = FileStack(filename)
61+
>>> str(fs2)
62+
'[]'
63+
>>> fs2.push(-32)
64+
>>> fs2.can_undo
65+
True
66+
>>> fs2.load()
67+
>>> fs2.can_undo
68+
False
69+
>>> str(fs2)
70+
'[-5, -4, -3, -2, -1, 909]'
71+
>>> fs == fs2
72+
True
73+
"""
74+
75+
76+
import abc
77+
import pickle
78+
79+
80+
class Undo(metaclass=abc.ABCMeta):
81+
82+
@abc.abstractmethod
83+
def __init__(self):
84+
self.__undos = []
85+
86+
87+
@abc.abstractproperty
88+
def can_undo(self):
89+
return bool(self.__undos)
90+
91+
92+
@abc.abstractmethod
93+
def undo(self):
94+
assert self.__undos, "nothing left to undo"
95+
self.__undos.pop()(self)
96+
97+
98+
def add_undo(self, undo):
99+
self.__undos.append(undo)
100+
101+
102+
def clear(self): # In class Undo
103+
self.__undos = []
104+
105+
106+
class Stack(Undo):
107+
108+
def __init__(self):
109+
super().__init__()
110+
self.__stack = []
111+
112+
113+
@property
114+
def can_undo(self):
115+
return super().can_undo
116+
117+
118+
def undo(self):
119+
super().undo()
120+
121+
122+
def push(self, item):
123+
self.__stack.append(item)
124+
self.add_undo(lambda self: self.__stack.pop())
125+
126+
127+
def pop(self):
128+
item = self.__stack.pop()
129+
self.add_undo(lambda self: self.__stack.append(item))
130+
return item
131+
132+
133+
def top(self):
134+
assert self.__stack, "Stack is empty"
135+
return self.__stack[-1]
136+
137+
138+
def __str__(self):
139+
return str(self.__stack)
140+
141+
142+
class NoFilenameError(Exception): pass
143+
144+
145+
class LoadSave:
146+
147+
def __init__(self, filename, *attribute_names):
148+
self.filename = filename
149+
self.__attribute_names = []
150+
for name in attribute_names:
151+
if name.startswith("__"):
152+
name = "_" + self.__class__.__name__ + name
153+
self.__attribute_names.append(name)
154+
155+
156+
def save(self):
157+
with open(self.filename, "wb") as fh:
158+
data = []
159+
for name in self.__attribute_names:
160+
data.append(getattr(self, name))
161+
pickle.dump(data, fh, pickle.HIGHEST_PROTOCOL)
162+
163+
164+
def load(self):
165+
with open(self.filename, "rb") as fh:
166+
data = pickle.load(fh)
167+
for name, value in zip(self.__attribute_names, data):
168+
setattr(self, name, value)
169+
170+
171+
class FileStack(Undo, LoadSave):
172+
173+
def __init__(self, filename):
174+
Undo.__init__(self)
175+
LoadSave.__init__(self, filename, "__stack")
176+
self.__stack = []
177+
178+
179+
def load(self):
180+
super().load()
181+
self.clear()
182+
183+
184+
@property
185+
def can_undo(self):
186+
return super().can_undo
187+
188+
189+
def undo(self):
190+
super().undo()
191+
192+
193+
def push(self, item):
194+
self.__stack.append(item)
195+
self.add_undo(lambda self: self.__stack.pop())
196+
197+
198+
def pop(self):
199+
item = self.__stack.pop()
200+
self.add_undo(lambda self: self.__stack.append(item))
201+
return item
202+
203+
204+
def top(self):
205+
assert self.__stack, "Stack is empty"
206+
return self.__stack[-1]
207+
208+
209+
def __eq__(self, other):
210+
return self.__stack == other.__stack
211+
212+
213+
def __str__(self):
214+
return str(self.__stack)
215+
216+
217+
if __name__ == "__main__":
218+
import doctest
219+
doctest.testmod()
220+

0 commit comments

Comments
 (0)