13-3.对类进行定制。写一个类,用来将浮点型值转换为金额。
1 class MoneyFmt(object): 2 3 def __init__(self, value=0.0, flag='-'): 4 5 self.value = float(value) 6 self.flag = flag 7 8 def dollarize(self): 9 """转换""" 10 val = round(self.value, 2) 11 strvalue = str(val) 12 if strvalue.startswith('-'): 13 strvalue = strvalue[1:] 14 len = strvalue.find('.') 15 while (len-3) > 0: 16 strvalue = strvalue[:len-3] + ',' + strvalue[len-3:] 17 len -= 3 18 return self.flag + '$' + strvalue 19 20 len = strvalue.find('.') 21 while (len-3) > 0: 22 strvalue = strvalue[:len-3] + ',' + strvalue[len-3:] 23 len -= 3 24 return '$' + strvalue 25 26 def update(self, newvalue=None): 27 """更新""" 28 if newvalue is not None: 29 self.value = float(newvalue) 30 31 def __nonzero__(self): 32 "非零" 33 if self.value == 0: 34 return False 35 return True 36 37 def __str__(self): 38 return self.dollarize() 39 40 def __repr__(self): 41 return repr(self.value)
13-4.用户注册。
建立一个用户数据库类,来管理一个系统,该系统要求用户在登录后才能访问某些资源。这个数据库类对用户进行管理,并在实例化操作时加载之前保存的用户信息,提供访问函数来添加或更新数据库的信息。在数据修改后,数据库会在垃圾回收时将新信息保存到磁盘。
1 from datetime import datetime 2 import shelve 3 4 class Userdatabase(object): 5 6 def __init__(self, dbfile): 7 """创建数据库""" 8 self.dbfile = dbfile 9 self.db = shelve.open(self.dbfile, 'c') 10 self.db.close() 11 12 def newuser(self, user, pwd): 13 """注册""" 14 self.db = shelve.open(self.dbfile, 'r') 15 if user in self.db: 16 print("User already exists") 17 self.db = shelve.open(self.dbfile, 'c') 18 self.db[user] = [user, pwd, datetime.now()] 19 self.db.close() 20 self.flag = False 21 22 def login(self, user, pwd): 23 """登录""" 24 self.db = shelve.open(self.dbfile, 'r') 25 if user not in self.db: 26 self.flag = False 27 elif self.db[user][1] == pwd: 28 self.flag = True 29 self.db.close() 30 31 def deluser(self, user): 32 """删除""" 33 self.db = {} 34 if self.flag: 35 self.db = shelve.open(self.dbfile, 'r') 36 if user in self.db: 37 self.db.pop(user) 38 else: 39 print('login first') 40 41 def updateuser(self, user, pwd): 42 """更新""" 43 if self.flag: 44 self.db = shelve.open(self.dbfile, 'c') 45 self.db[user] = [user, pwd, datetime.now()] 46 self.db[user] = self.db[user] 47 else: 48 print('login first') 49 50 def listall(self): 51 """查看""" 52 if self.flag: 53 for user in self.db: 54 print(self.db[user][0], self.db[user][1]) 55 else: 56 print('login first') 57 58 if __name__ == '__main__': 59 user = Userdatabase('shelve.data') 60 user.newuser('admin', '123456') 61 user.login('admin', '123456') 62 user.updateuser('admin', '123456') 63 user.updateuser('test', '123456') 64 user.listall() 65 user.deluser('test') 66 user.listall()
13-5.几何。创建一个由有序数值对(x,y)组成的Point类,代表某个点的X和Y坐标。
1 class Point(object): 2 3 def __init__(self, x=0, y=0): 4 self.x = x 5 self.y = y 6 7 def __str__(self): 8 return '(%d, %d)' % (self.x, self.y) 9 10 if __name__ == '__main__': 11 p = Point(1, 1) 12 print(p)
13-6.几何。创建一个直线类,除主要属性:一对坐标值外,它还具有长度和斜线属性。你需要覆盖__repr__()方法,使得代表那条直线的字符串表示形式是由一对元组构成的元组。
1 from math import sqrt 2 3 class Beeline(object): 4 5 def __init__(self, x1=0, y1=0, x2=0, y2=2): 6 self.x1 = x1 7 self.y1 = y1 8 self.x2 = x2 9 self.y2 = y2 10 self.length = 0 11 self.slope = None 12 13 def getLength(self): 14 """长度""" 15 if self.x1 == self.x2 and self.y1 == self.y2: 16 self.length = 0 17 elif self.x1 == self.x2: 18 self.length = abs(self.y2 - self.y1) 19 elif self.y1 == self.y2: 20 self.length = abs(self.x2 - self.x1) 21 else: 22 self.length = sqrt((self.y2 - self.y1)**2 + (self.x2 - self.x1)**2) 23 return self.length 24 25 def getSlope(self): 26 """斜率""" 27 if self.length == 0: 28 self.slope = None 29 elif self.x1 == self.x2 or self.y1 == self.y2: 30 self.slope = None 31 else: 32 self.slope = float(self.y2 - self.y1) / (self.x2 - self.x1) 33 return self.slope 34 35 def __str__(self): 36 return '((%d, %d),(%d, %d))' % (self.x1, self.y1, self.x2, self.y2) 37 38 __repr__ = __str__ 39 40 if __name__ == '__main__': 41 b = Beeline(1, 2, 3, 4) 42 print(b) 43 print('Length is %f' % b.getLength()) 44 print('Slope is %s' % b.getSlope())
13-7.数据类。提供一个time模块的接口,允许用户按照自己给定的时间格式来查看日期。你的类应该维护一个日期值,并用给定的时间创建一个实例,如果没有给出时间值,程序执行时会默认采用当前的系统时间。
1 import time 2 3 class TimeFormat(object): 4 5 def __init__(self, t=time.time()): 6 self.mytime = t 7 8 def update(self, t=time.time()): 9 self.mytime = t 10 11 def display(self, ft=None): 12 fmt = {} 13 fmt['MDY'] = '%m/%d/%y' 14 fmt['MDYY'] = '%m/%d/%Y' 15 fmt['DMY'] = '%d/%m/%y' 16 fmt['DMYY'] = '%d/%m/%Y' 17 fmt['MODYY'] = '%b %d,%Y' 18 if ft in fmt: 19 return (time.strftime(fmt[ft], time.localtime(self.mytime))) 20 return time.ctime(self.mytime) 21 22 if __name__ == '__main__': 23 tf = TimeFormat() 24 print(tf.display()) 25 print(tf.display('MDY')) 26 print(tf.display('MDYY')) 27 print(tf.display('DMY')) 28 print(tf.display('DMYY')) 29 print(tf.display('MODYY')) 30 tf.update(time.time() + 60) 31 print(tf.display())
13-8.堆栈类。
实现一个堆栈类,类中应该有push()和pop()方法,还有一个isempty()方法,如果堆栈是空的,返回布尔值1,否则返回0。
1 class Stack(object): 2 3 def __init__(self, l=[]): 4 self.l = l 5 6 def isempty(self): 7 if len(self.l) == 0: 8 return 1 9 return 0 10 11 def push(self, element): 12 print('pushed [', element, ']') 13 self.l.append(element) 14 15 def peek(self): 16 if self.isempty(): 17 print('can not peek from an empty stack') 18 return self.l[0] 19 20 def pop(self): 21 if self.isempty(): 22 print('can not pop from an empty stack') 23 else: 24 print('removed [', self.l.pop(), ']') 25 26 def viewstack(self): 27 print(self.l) 28 29 if __name__ == '__main__': 30 s = Stack() 31 s.viewstack() 32 s.pop() 33 s.viewstack() 34 s.push(2) 35 s.viewstack()
13-9.队列类。实现一个队列类,这个类必须支持下面几种方法:enqueue()在队列的尾部加入一个新的元素,dequeue()在队列的头部取出一个元素,返回它并且把它从列表中删除。
1 class Queue(object): 2 3 def __init__(self, l=[]): 4 self.l = l 5 6 def enqueue(self, element): 7 print('enter queue [', element, ']') 8 self.l.append(element) 9 10 def dequeue(self): 11 if self.l: 12 print('removed [', self.l.pop(0), ']') 13 else: 14 print('can not pop from an empty stack') 15 16 def viewstack(self): 17 print(self.l) 18 19 if __name__ == '__main__': 20 q = Queue([1, 2, 3]) 21 q.viewstack() 22 q.enqueue(4) 23 q.dequeue() 24 q.viewstack()
13-10.堆栈和队列。编写一个类,定义一个能够同时具有堆栈和队列操作行为的数据结构。这个类和Perl语言中数组相像。需要实现四个方法。
1 class FifoLifo(object): 2 3 def __init__(self, l=[]): 4 self.l = l 5 6 def shift(self): 7 """删除头""" 8 if self.l: 9 print('removed [', self.l.pop(0), ']') 10 else: 11 print('can not pop from an empty stack') 12 13 def unshift(self, element): 14 """插入头""" 15 print('inserted [', element, ']') 16 self.l.insert(0, element) 17 18 def push(self, element): 19 """插入尾""" 20 print('pushed [', element, ']') 21 self.l.append(element) 22 23 def pop(self): 24 """删除尾""" 25 if self.l: 26 print('removed [', self.l.pop(), ']') 27 else: 28 print('can not pop from an empty stack') 29 30 def viewstack(self): 31 print(self.l) 32 33 if __name__ == '__main__': 34 f = FifoLifo([1, 2, 3, 4, 5]) 35 f.viewstack() 36 f.shift() 37 f.unshift(6) 38 f.push(0) 39 f.pop() 40 f.viewstack()
13-11.电子商务。
你需要为一家B2C零售商编写一个基础的电子商务引擎。你需要写一个针对顾客的类User,一个对应存货清单的类Item,还有一个对应购物车的类叫Cart。货物放到购物车里,顾客可以有多个购物车。同时购物车里可以有多个货物,包括多个同样的货物。
1 class Item(object): 2 """物品价格清单""" 3 def __init__(self, product, price): 4 self.product = product 5 self.price = price 6 7 def __str__(self): 8 return '(%s, %.2f)' % (self.product, self.price) 9 10 class Cart(object): 11 """购物车""" 12 def __init__(self, cartname): 13 self.cartname = cartname 14 self.cartlist = {} 15 16 def appenditem(self, item, count=1): 17 """增加数量""" 18 if item not in self.cartlist: 19 self.cartlist[item] = count 20 else: 21 self.cartlist[item] += count 22 23 def showcart(self): 24 """查看""" 25 for i in self.cartlist: 26 print(self.cartname, i, self.cartlist[i]) 27 28 def deleteitem(self, item, count=1): 29 """减少数量""" 30 if item in self.cartlist and self.cartlist[item]>=count: 31 self.cartlist[item] -= count 32 if self.cartlist[item] == 0: 33 self.cartlist.pop(item) 34 35 class User(object): 36 """顾客""" 37 def __init__(self, name): 38 self.name = name 39 self.userdb = [] 40 41 def appendcart(self, cart): 42 self.userdb.append(cart.cartname) 43 44 def showuser(self): 45 print(self.name, self.userdb) 46 47 if __name__ == '__main__': 48 i1 = Item('huawei', 15000) 49 i2 = Item('iphone', 7000) 50 print(i1, i2) 51 c1 = Cart('cart1') 52 c2 = Cart('cart2') 53 c3 = Cart('cart3') 54 c1.appenditem(i1, 1) 55 c1.appenditem(i2, 1) 56 c2.appenditem(i2, 2) 57 c3.appenditem(i1, 2) 58 c1.showcart() 59 c2.showcart() 60 c3.showcart() 61 u1 = User('Tom') 62 u2 = User('Jerry') 63 u1.appendcart(c1) 64 u2.appendcart(c2) 65 u2.appendcart(c3) 66 u1.showuser() 67 u2.showuser()
13-12.聊天室。
你需要三个类:一个Message类,它包含一个消息字符串以及诸如广播、单方收件人等其他信息。一个User类,包含了进入你聊天室的某个人的所有信息。一个Room类,它体现了一个更加复杂的聊天系统,用户可以在聊天时创建单独的房间,并邀请其他人加入。
1 class Message(object): 2 3 def __init__(self, msg='', broadcast=False, froms='', to=''): 4 5 self.msg = msg 6 self.broadcast = broadcast 7 self.froms = froms 8 self.to = to 9 10 def __str__(self): 11 """广播""" 12 if self.broadcast: 13 return 'message: %s from %s send to everyone' % (self.msg, self.froms) 14 else: 15 return 'message: %s from %s send to %s' % (self.msg, self.froms, self.to) 16 17 18 class User(object): 19 20 hear = {'everyone': ''} 21 22 def __init__(self, name, sex, age): 23 24 self.name = name 25 self.sex = sex 26 self.age = age 27 28 def __del__(self): 29 30 User.hear.clear() 31 32 def __str__(self): 33 34 return 'user:%s ,sex:%s ,age:%d' % (self.name, self.sex, self.age) 35 36 def talk(self, to='', msg=''): 37 """发送广播""" 38 if to == 'everyone': 39 m = Message(msg, True, self.name) 40 User.hear['everyone'] = m 41 elif to: 42 m = Message(msg, False, self.name, to) 43 User.hear[to] = m 44 else: 45 print('receiver can not be empty') 46 47 def hearmsg(self): 48 """显示消息""" 49 if self.name in User.hear: 50 print(User.hear[self.name]) 51 elif User.hear['everyone']: 52 print(User.hear['everyone']) 53 else: 54 print('no msg for %s' % self.name) 55 56 def talkroom(self, room, to='', msg=''): 57 """room广播""" 58 if to == 'everyone': 59 m = Message(msg, True, self.name) 60 room.receive(m) 61 elif to: 62 m = Message(msg, False, self.name, to) 63 room.receive(m) 64 else: 65 print('receiver can not be empty') 66 67 def hearroom(self, m): 68 """显示room消息""" 69 print('room %s' % m) 70 71 def createroom(self, name, count=3): 72 """room人员""" 73 return Room(name, count) 74 75 76 class Room(object): 77 78 def __init__(self, rname, count=3): 79 80 self.rname = rname 81 self.count = count 82 self.userlist = [] 83 84 def adduser(self, user): 85 """room用户邀请""" 86 if len(self.userlist) <= self.count: 87 self.userlist.append(user) 88 else: 89 print('user number limits') 90 91 def receive(self, m): 92 """room广播""" 93 if m.broadcast: 94 print('room %s' % m) 95 else: 96 for user in self.userlist: 97 if user.name == m.to: 98 user.hearroom(m) 99 100 101 if __name__ == '__main__': 102 u1 = User('bob', 'male', 33) 103 u2 = User('jim', 'female', 31) 104 u3 = User('Tom', 'female', 31) 105 u1.talk('jim', 'hello') 106 u2.hearmsg() 107 u3.hearmsg() 108 room1 = u2.createroom('girls', 2) 109 room1.adduser(u2) 110 room1.adduser(u3) 111 u2.talkroom(room1, 'Tom', 'hello') 112 u3.talkroom(room1, 'everyone', 'hello')
13-13. 股票投资组合类。你的数据库中记录了每个公司的名字、股票代码、购买日期、购买价格和持股数量。需要编写的方法包括:添加新代号、删除代号、根据当前价格计算出的YTD或年回报率。
1 class Stock(object): 2 3 def __init__(self, name, code, date, price, amount): 4 5 self.name = name 6 self.code = code 7 self.date = date 8 self.price = price 9 self.amount = amount 10 11 def __str__(self): 12 return '%s %s %s %.2f %d' % (self.name, self.code, self.date, self.price, self.amount) 13 14 class Operator(object): 15 16 def __init__(self): 17 18 self.db = {} 19 20 def newcode(self, stock): 21 22 self.db.setdefault(stock.code, [stock.name, stock.date, stock.price, stock.amount]) 23 24 def popcode(self, code): 25 26 self.db.pop(code) 27 28 def years(self, year): 29 30 if (year % 4 == 0 and year % 100 != 0) or (year % 4 == 0 and year % 400 == 0): 31 return True 32 33 def months(self, str1, str2): 34 35 month1 = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 36 month2 = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 37 bdate = str1.split('/') 38 bdate[0], bdate[1], bdate[2] = int(bdate[0]), int(bdate[1]), int(bdate[2]) 39 edate = str2.split('/') 40 edate[0], edate[1], edate[2] = int(edate[0]), int(edate[1]), int(edate[2]) 41 42 if bdate == edate: 43 return 0 44 45 elif bdate[1] == edate[1] and bdate[2] == bdate[2]: 46 return abs(bdate[0]-edate[0]) 47 48 elif bdate[1] != edate[1] and bdate[2] == edate[2]: 49 bdays = 0 50 edays = 0 51 if self.years(bdate[2]): 52 for i in range(1, bdate[1]): 53 bdays += month2[i] 54 bdays = bdays + bdate[0] 55 for i in range(1, edate[1]): 56 edays += month2[i] 57 edays = edays + edate[0] 58 return abs(edays - bdays) 59 else: 60 for i in range(1, bdate[1]): 61 bdays += month1[i] 62 bdays = bdays + bdate[0] 63 for i in range(1, edate[1]): 64 edays += month1[i] 65 edays = edays + edate[0] 66 return abs(edays - bdays) 67 68 elif bdate[2] != edate[2]: 69 days = 0 70 for i in range(bdate[2]+1, edate[2]): 71 if self.years(i): 72 days += 366 73 else: 74 days += 365 75 if self.years(bdate[2]): 76 for i in range(bdate[1]+1, 13): 77 days += month2[i] 78 days += (month2[bdate[1]]-bdate[0]) 79 else: 80 for i in range(bdate[1]+1, 13): 81 days += month1[i] 82 days += (month1[bdate[1] - bdate[0]]) 83 if self.years(edate[2]): 84 for i in range(1, edate[1]): 85 days += month2[i] 86 days += edate[0] 87 return days 88 else: 89 for i in range(1, edate[1]): 90 days += month1[i] 91 days += edate[0] 92 return days 93 94 def YTD(self, stock, newprice, newdate): 95 96 holddays = self.months(stock.date, newdate) 97 costmoney = stock.price * stock.amount 98 curmoney = newprice * stock.amount 99 benifit = curmoney - costmoney 100 101 if stock.code in self.db: 102 print('YTD of %s is %.2f %%' %(stock.code, benifit/holddays*365/costmoney)) 103 else: 104 print('Stock %s does not exists' % stock.code) 105 106 def showdb(self): 107 print(self.db) 108 109 s1 = Stock('xx', '123', '01/01/2019', 1.0, 1000) 110 s2 = Stock('yy', '234', '05/01/2019', 18.0, 1000) 111 op1 = Operator() 112 op1.newcode(s1) 113 op1.newcode(s2) 114 op1.showdb() 115 op1.popcode('234') 116 op1.showdb() 117 op1.YTD(s1, 1.01, '11/03/2019')
13-14.DOS。为DOS机器编写一个Unix操作界面的shell。你向用户提供一个命令行,使得用户可以在那里输入unix命令,你可以对这些命令进行解释,并把返回相应的输出。
1 import os 2 3 class Shell(object): 4 5 def __init__(self): 6 7 self.cmddict = {'ls': 'dir', 'more': 'more', 'cat': 'type', 'cp': 'copy', 'mv': 'ren', 'rm': 'del'} 8 9 def translate(self, cmd): 10 11 opt = cmd.split() 12 if opt[0] in self.cmddict: 13 opt[0] = self.cmddict[opt[0]] 14 return ' '.join(opt) 15 16 def start(self): 17 18 while True: 19 cmd = input('#') 20 cmd = self.translate(cmd) 21 if cmd == 'exit': 22 break 23 24 output = os.popen(cmd).readlines() 25 for out in output: 26 print(out) 27 28 if __name__ == '__main__': 29 s = Shell() 30 s.start()
13-16.授权和函数编程。
(a)请为示例中的CanOpen类编写一个writelines()方法,这个新函数可以一次读入多行文本,然后将文本转化为大写的形式。
(b)在writelines()方法中添加一个参数,用这个参数来指明是否需要为每行文本加上一个换行符。此参数的默认值是False,表示不加换行符。
1 import os 2 3 class CapOpen(object): 4 5 def __init__(self, fn, mode='r', buf=-1): 6 7 self.file = open(fn, mode, buf) 8 9 def __str__(self): 10 11 return str(self.file) 12 13 def __repr__(self): 14 15 return 'self.file' 16 17 def write(self, line): 18 19 self.file.write(line.upper()) 20 21 def writelines(self, lines, enter=False): 22 23 for line in lines: 24 if enter: 25 line += os.linesep 26 self.write(line) 27 28 def __getattr__(self, attr): 29 30 return getattr(self.file, attr) 31 32 if __name__ == '__main__': 33 f1 = CapOpen('test.txt') 34 lines = f1.readlines() 35 f1.close() 36 37 f2 = CapOpen('newtest.txt', 'w') 38 f2.writelines(lines, False) 39 f2.close()
13-17. 数值类型子类化。在示例13.3中所看到的moneyfmt.py脚本基础上修改它,使得它可以扩展Python的浮点类型。请确保它支持所有操作,而且是不可变的。
1 class MoneyFmt(float): 2 3 def __new__(cls, value=0.0, flag='-'): 4 5 cls.flag = flag 6 cls.value = super(MoneyFmt, cls).__new__(cls, value) 7 return cls.value 8 9 def dollarize(cls): 10 """转换""" 11 val = round(cls.value, 2) 12 strvalue = str(val) 13 if strvalue.startswith('-'): 14 strvalue = strvalue[1:] 15 len = strvalue.find('.') 16 while (len-3) > 0: 17 strvalue = strvalue[:len-3] + ',' + strvalue[len-3:] 18 len -= 3 19 return cls.flag + '$' + strvalue 20 21 len = strvalue.find('.') 22 while (len-3) > 0: 23 strvalue = strvalue[:len-3] + ',' + strvalue[len-3:] 24 len -= 3 25 return '$' + strvalue 26 27 def __nonzero__(cls): 28 "非零" 29 if cls.value == 0: 30 return False 31 return True 32 33 def __str__(cls): 34 35 return cls.dollarize() 36 37 38 if __name__ == '__main__': 39 money = input('Money: ') 40 moneyfmt = MoneyFmt(money) 41 print(moneyfmt.dollarize())
13-18. 序列类型子类化。模仿前面练习13-4中的用户注册类的解决方案,编写一个子类。要求允许用户修改密码,但密码有效期是12个月,过期后不能重复使用。
1 import time, shelve 2 3 class Userdatabase(object): 4 5 def __init__(self, dbfile): 6 """创建数据库""" 7 self.dbfile = dbfile 8 self.db = shelve.open(self.dbfile, 'c') 9 self.db.close() 10 11 def newuser(self, user, pwd): 12 """注册""" 13 14 self.db = shelve.open(self.dbfile, 'r') 15 if user in self.db: 16 print("User already exists") 17 self.db = shelve.open(self.dbfile, 'c') 18 self.db[user] = [user, [pwd, time.time()], time.ctime()] 19 self.db.close() 20 self.flag = False 21 22 def login(self, user, pwd): 23 """登录""" 24 self.db = shelve.open(self.dbfile, 'r') 25 if user not in self.db: 26 self.flag = False 27 elif self.db[user][1][0] == pwd: 28 if self.db[user][1][-1] - time.time() > 365*24*60*60: 29 print("Password has expired") 30 self.flag = False 31 else: 32 self.flag = True 33 self.db.close() 34 35 def deluser(self, user): 36 """删除""" 37 self.db = {} 38 if self.flag: 39 self.db = shelve.open(self.dbfile, 'r') 40 if user in self.db: 41 self.db.pop(user) 42 else: 43 print('login first') 44 45 def updateuser(self, user, pwd): 46 """更新密码""" 47 newdb = {} 48 if self.flag: 49 self.db = shelve.open(self.dbfile, 'r') 50 if pwd in self.db[user][1]: 51 print("The new password cannot be the same as the used password") 52 else: 53 value = [user, self.db[user][1], time.ctime()] 54 value[1].insert(0, pwd) 55 value[1][-1] = time.time() 56 newdb[user] = value 57 self.db = shelve.open(self.dbfile, 'c') 58 self.db[user] = newdb[user] 59 print(self.db[user]) 60 else: 61 print('login first') 62 63 64 def listall(self): 65 """查看""" 66 if self.flag: 67 for user in self.db: 68 print(self.db[user][0], self.db[user][1][0]) 69 else: 70 print('login first') 71 72 if __name__ == '__main__': 73 user = Userdatabase('shelve.data') 74 user.newuser('admin', '123456') 75 user.newuser('test', '123456') 76 user.login('admin', '123456') 77 user.login('test', '123456') 78 user.updateuser('admin', '123456') 79 user.updateuser('test', '123456') 80 user.listall() 81 user.deluser('test') 82 user.listall()
13-20.类的定制。改进脚本time60.py
(a)允许“空”实例化:如果小时和分钟的值没有给出,默认为0小时0分钟。
(b)用0占位组成两位数的形式,因为当前的时间格式不符合要求。
(c)除了用hours(hr)和minutes(min)进行初始化外,还支持以下时间输入格式:
一个由小时和分钟组成的元组,如(10,30)
一个由小时和分钟组成的字典,如{'hr':10, 'min':30}
一个代表小时和分钟的字符串,如"10:30"
(e)实现__repr__()。
(f)添加60进制的运算功能。
1 class Time60(object): 2 'Time60 - track hours and minutes' 3 4 def __init__(self, *time): 5 'Time60 constructor - takes hours and minutes' 6 if len(time) == 1: 7 if type(time[0]) == tuple: 8 self.hr = time[0][0] 9 self.min = time[0][1] 10 elif type(time[0]) == dict: 11 self.hr = time[0]['hr'] 12 self.min = time[0]['min'] 13 elif type(time[0]) == str: 14 all = time[0].split(':') 15 self.hr = int(all[0]) 16 self.min = int(all[1]) 17 18 elif len(time) == 0: 19 self.hr = 0 20 self.min = 0 21 22 else: 23 self.hr = time[0] 24 self.min = time[1] 25 26 def __str__(self): 27 'Time60 - string representation' 28 return '%02d:%02d' % (self.hr, self.min) 29 30 def __repr__(self): 31 32 return repr('%02d:%02d' % (self.hr, self.min)) 33 34 def __add__(self, other): 35 'Time60 - overloading the addition operator' 36 hr = self.hr + other.hr 37 min = self.min + other.min 38 ahr = min // 60 39 min %= 60 40 hr += ahr 41 if hr > 23: hr = 0 42 return self.__class__(hr, min) 43 44 def __iadd__(self, other): 45 'Time60 - overloading in-place addition' 46 self.hr += other.hr 47 self.min += other.min 48 return self 49 50 print(Time60()) 51 print(Time60(10, 30)) 52 print(Time60("15:31")) 53 print(Time60((10, 30))) 54 print(Time60({'hr':11, 'min':15})) 55 print(Time60(1, 5)) 56 print(Time60("15:31") + Time60(8,31))