注:该练习题来自(Python 核心编程 第二版)第13章 练习题13-3,题目如下:
13-3.对类进行定制,写一个类,用来将浮点型值转化为金额,在本练习里,我们使用美国货币,但读者也可以自选任意货币。
基本任务:编写一个dollarize()函数,它以一个浮点型值作为输入,返回一个字符串形式的金额数。比如说:
dollarize(1234567.8901) ﹦﹥ ‘$1,234,567.89’
dollarize()返回的金额数里应该允许有逗号(比如1,000,000)和美元的货币符号。如果有负号,它必须出现在美元符号的左边。完成这项工作后,你就可以把它转换成一个有用的类,名为MoneyFmt。
MoneyFmt类里只有一个数据值(即金额),和5个方法(你可以随意编写其他方法)。__init__()构造器对数据进行初始化,update()方法把数据值替换成一个新值,__nonzero__() 是布尔型的,当数据值非零时返回True,__repr__()方法以浮点型的形式返回金额,而__str__()方法采用和dollarize()一样的字符格式显示该值。
(a) 编写update()方法,以实现数据值的修改功能。
(b) 以你已经编写的dollarize()的代码为基础,编写__str__()方法的代码。
(c) 纠正__nonzero__()方法中的错误,这个错误以为所有小于1的数值,例如:50美分($0.50),返回假值(False)。
(d)附加题:允许用户通过一个可选的参数指定是把负数数值显示在一对尖括号里还是显示一个负号。默认参数是使用标准的负号。
下面是我写出的答案,供以后参考:
#!/usr/bin/env python class MoneyFmt(object): def __init__(self, money, mark=False): self.__money = money self.__mark = mark def __str__(self): return str(self.__dollarize()) def __repr__(self): return ‘%s‘ % self.__money def __nonzero__(self): return bool(self.__money) def update(self, new_money): self.__money = new_money def __dollarize(self): if "-" not in str(self.__money): li = list(str(self.__money).split(‘.‘)[0]) else: li = list(str(self.__money).split(‘.‘)[0])[1:] if len(li) <= 3: if "-" not in str(self.__money): return "$%.2f" % self.__money else: if self.__mark == False: return "-$%.2f" % abs(self.__money) elif self.__mark == True: return "<->$%.2f" % abs(self.__money) else: rev = "%.2f" % self.__money if "-" not in rev: li = list(rev.split(‘.‘)[0]) else: li = list(rev.split(‘.‘)[0])[1:] length = len(li) x = divmod(length, 3) if x[1] != 0: count = x[0] else: count = x[0]-1 i = 1 while i <= count: li.insert((length-3), ‘,‘) i += 1 length -= 3 if "-" not in rev: string = "$" + ‘‘.join(li) + rev[-3:] else: if self.__mark == False: string = "-$" + ‘‘.join(li) + rev[-3:] elif self.__mark == True: string = "<->$" + ‘‘.join(li) + rev[-3:] return string def test(): x = MoneyFmt(123456.789) y = MoneyFmt(0.5) z = MoneyFmt(-123) m = MoneyFmt(-123.456,mark=True) print x print y print z print m if __name__ == "__main__": test()
该程序可当做模块导入使用,也可直接运行,直接运行结果如下:
$123,456.79
$0.50
-$123.00
<->$123.46