В настоящее время он не будет делать то, что вы хотите вообще. Вы не можете умножить ваш m_decimal ни на что: он всегда будет возвращать None из-за пропущенного оператора return:
def __mul__ ( self, other ) :
print (type(other))
return Decimal.__mul__ ( self, other )
Даже с добавленным возвратом вы все равно не можете выполнить D (500000) * 2.2, поскольку число с плавающей запятой все еще нуждается в преобразовании в десятичное число до десятичного числа. Кроме того, repr здесь не подходит:
>>> repr(2.1)
'2.1000000000000001'
>>> str(2.1)
'2.1'
То, как я бы это сделал, это сделать метод класса из плавания
@classmethod
def fromfloat(cls, f):
return cls(str(f))
Затем переопределите метод mul, чтобы проверить тип other, и запустите на нем m_Decimal.fromfloat (), если он является float:
class m_Decimal(Decimal):
@classmethod
def fromfloat(cls, f):
return cls(str(f))
def __mul__(self, other):
if isinstance(other, float):
other = m_Decimal.fromfloat(other)
return Decimal.__mul__(self,other)
Тогда он будет работать точно так, как вы ожидаете. Лично я не переопределил бы новый метод, поскольку мне кажется более чистым использовать метод fromfloat (). Но это только мое мнение.
Как сказал Дирк, вам не нужно беспокоиться о преобразовании, поскольку isinstance работает с подклассами. Единственная проблема, с которой вы можете столкнуться, это то, что Decimal * m_Decimal будет возвращать десятичное число, а не ваш подкласс:
>>> Decimal(2) * m_Decimal(2) * 2.2
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
Decimal(2) * m_Decimal(2) * 2.2
TypeError: unsupported operand type(s) for *: 'Decimal' and 'float'
Есть два способа это исправить. Во-первых, нужно добавить явное преобразование к методу магии m_Decimal:
def __mul__(self, other):
if isinstance(other, float):
other = m_Decimal.fromfloat(other)
return m_Decimal(Decimal.__mul__(self,other))
Другой способ, который я, вероятно, не рекомендовал бы, - это "Monkeypatch" десятичный модуль:
decimal._Decimal = decimal.Decimal
decimal.Decimal = m_Decimal