quantity.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python
  3. from functools import total_ordering
  4. from bson.decimal128 import Decimal128
  5. from apilib.numerics import force_decimal, UnitBase, quantize
  6. @total_ordering
  7. class Quantity(UnitBase):
  8. """
  9. 主要用来记录消费的数额
  10. """
  11. def __init__(self, amount, places='0.0001'):
  12. if isinstance(amount, Quantity):
  13. self._amount = amount.amount
  14. self._amount = quantize(force_decimal(amount), places=places)
  15. @property
  16. def amount(self):
  17. return self._amount
  18. @property
  19. def mongo_amount(self):
  20. return Decimal128(self._amount)
  21. def _format(self, string):
  22. # type:(str)->str
  23. return string.format(type=self.__class__.__name__)
  24. def __str__(self):
  25. return u'{amount}'.format(amount=self._amount)
  26. def __repr__(self):
  27. return '{type} {amount}'.format(type=self.__class__.__name__, amount=self._amount)
  28. def __eq__(self, other):
  29. if isinstance(other, Quantity):
  30. return self._amount == other._amount
  31. else:
  32. raise TypeError(self._format('{type} can only be compared(__eq__) with another {type}'))
  33. def __lt__(self, other):
  34. if isinstance(other, Quantity):
  35. return self._amount < other._amount
  36. else:
  37. raise TypeError(self._format('{type} can only be compared(__lt__) with another {type}'))
  38. def __mul__(self, other):
  39. if isinstance(other, Quantity):
  40. raise TypeError(self._format('{type} cannot be multiplied by {type}'))
  41. else:
  42. return self.__class__(self.amount * other)
  43. def __div__(self, other):
  44. if isinstance(other, Quantity):
  45. raise TypeError(self._format('{type} cannot be divided by {type}'))
  46. else:
  47. return self.__class__(self.amount / other)
  48. def __add__(self, other):
  49. if isinstance(other, Quantity):
  50. return self.__class__(self._amount + other._amount)
  51. else:
  52. raise TypeError(self._format('{type} cannot be added to {type}'))
  53. def __sub__(self, other):
  54. if isinstance(other, Quantity):
  55. return self.__class__(self._amount - other._amount)
  56. else:
  57. raise TypeError(self._format('{type} cannot be subtracted to {type}'))
  58. def __float__(self):
  59. return float(self.amount)