# -*- coding: utf-8 -*- #!/usr/bin/env python from functools import total_ordering from bson.decimal128 import Decimal128 from apilib.numerics import force_decimal, UnitBase, quantize @total_ordering class Quantity(UnitBase): """ 主要用来记录消费的数额 """ def __init__(self, amount, places='0.0001'): if isinstance(amount, Quantity): self._amount = amount.amount self._amount = quantize(force_decimal(amount), places=places) @property def amount(self): return self._amount @property def mongo_amount(self): return Decimal128(self._amount) def _format(self, string): # type:(str)->str return string.format(type=self.__class__.__name__) def __str__(self): return u'{amount}'.format(amount=self._amount) def __repr__(self): return '{type} {amount}'.format(type=self.__class__.__name__, amount=self._amount) def __eq__(self, other): if isinstance(other, Quantity): return self._amount == other._amount else: raise TypeError(self._format('{type} can only be compared(__eq__) with another {type}')) def __lt__(self, other): if isinstance(other, Quantity): return self._amount < other._amount else: raise TypeError(self._format('{type} can only be compared(__lt__) with another {type}')) def __mul__(self, other): if isinstance(other, Quantity): raise TypeError(self._format('{type} cannot be multiplied by {type}')) else: return self.__class__(self.amount * other) def __div__(self, other): if isinstance(other, Quantity): raise TypeError(self._format('{type} cannot be divided by {type}')) else: return self.__class__(self.amount / other) def __add__(self, other): if isinstance(other, Quantity): return self.__class__(self._amount + other._amount) else: raise TypeError(self._format('{type} cannot be added to {type}')) def __sub__(self, other): if isinstance(other, Quantity): return self.__class__(self._amount - other._amount) else: raise TypeError(self._format('{type} cannot be subtracted to {type}')) def __float__(self): return float(self.amount)