【发布时间】:2010-01-11 19:42:31
【问题描述】:
我想在我的 Python 程序中使用 Decimal 类进行财务计算。不能与浮点数一起使用的小数 - 它们需要首先显式转换为字符串。 所以我决定继承 Decimal 以便能够在没有显式转换的情况下使用浮点数。
m_Decimal.py:
# -*- coding: utf-8 -*-
import decimal
Decimal = decimal.Decimal
def floatCheck ( obj ) : # usually Decimal does not work with floats
return repr ( obj ) if isinstance ( obj, float ) else obj # this automatically converts floats to Decimal
class m_Decimal ( Decimal ) :
__integral = Decimal ( 1 )
def __new__ ( cls, value = 0 ) :
return Decimal.__new__ ( cls, floatCheck ( value ) )
def __str__ ( self ) :
return str ( self.quantize ( self.__integral ) if self == self.to_integral () else self.normalize () ) # http://docs.python.org/library/decimal.html#decimal-faq
def __mul__ ( self, other ) :
print (type(other))
Decimal.__mul__ ( self, other )
D = m_Decimal
print ( D(5000000)*D(2.2))
所以现在我应该能够写D(5000000)*2.2 而不是写D(5000000)*D(2.2) 而不会引发异常。
我有几个问题:
我的决定会给我带来什么麻烦吗?
在
D(5000000)*D(2.2)的情况下重新实现__mul__不起作用,因为另一个参数的类型为class '__main__.m_Decimal',但您可以在十进制模块中看到:
decimal.py,第 5292 行:
def _convert_other(other, raiseit=False):
"""Convert other to Decimal.
Verifies that it's ok to use in an implicit construction.
"""
if isinstance(other, Decimal):
return other
if isinstance(other, (int, long)):
return Decimal(other)
if raiseit:
raise TypeError("Unable to convert %s to Decimal" % other)
return NotImplemented
decimal 模块需要参数是 Decimal 或 int。这意味着我应该先将我的 m_Decimal 对象转换为字符串,然后再转换为十进制。但这很浪费 - m_Decimal 是 Decimal 的后代 - 我如何使用它来使课程更快(Decimal 已经很慢了)。
- 当 cDecimal 出现时,这个子类化会起作用吗?
【问题讨论】:
-
请记住,将 Decimal 乘以 float 会导致 Decimal 精度降低,这就是为什么一开始没有实施此操作的原因。
-
不确定,为什么必须转换?
isinstance正确考虑了子类化...isinstance(d, m_Decimal)暗示isinstance(d, Decimal)。 -
你的操作肯定会导致小数的用途出现问题。如果您不需要它们或不了解它们的用途,请不要使用它们;我建议您检查 IEEE 754 标准。
标签: python decimal subclassing