I'm trying to inherit Decimal and create a math class than can handle polymorphic input. The problem I'm running into is that nothing I do seems to allow me to create duplicate instances.
I've looked at dozens of examples, but nothing I've found actually creates multiple instances from an internal constructor. They all do it from outside.
To have overridden math functions with polymorphic input, the instance-constructor MUST be internal to the class. There is no other way. I've been over this ten different ways, looked at tons of online docs ( mostly flat out wrong ) Hopefully somebody here can help.
#### FOO.py
import sys
from decimal import Decimal, getcontext
import socket
import operator
import re
import copy
class Amount(Decimal):
def __init__(self):
instancehex = hex(id(self))
print ("class: ", self.__class__.__name__)
print ("baseclass: ", self.__class__.__base__)
print ("instance: ", instancehex)
super(type(self),self).__init__() # inherit decimal for getcontext()
print ("postinitclass: ", self.__class__.__name__)
print ("postinitbaseclass: ", self.__class__.__base__)
print ("postinitinstance: ", instancehex)
# these are instance variables? If not, how from inside an instance-constructor?
self.value = Decimal(0.0) # our initial value
self.isdefined = False #
def newamount(self, *arg):
# this should call __init__? Doesn't happen.
thisobject = copy.deepcopy(self)
# these should be different memory addresses?
selfhex = hex(id(self))
thishex = hex(id(thisobject))
print ("\tself: ", str(selfhex))
print ("\tcopy: ", str(thishex))
if len(arg):
polyinput = arg[0]
thisobject.setvalue(polyinput)
self.isdefined = True
return(thisobject)
def setvalue(self,polyinput):
# polymorphic numeracy
print ("\t\tsetting from: ", polyinput.__class__.__name__)
if polyinput.__class__.__name__ == "Amount":
self.value = (polyinput.value)
elif polyinput.__class__.__name__ == "float":
self.value.from_float(polyinput)
def __add__(self,polyinput):
rcvamount = self.newamount(polyinput)
sumamount = self.newamount()
print ("ADDING:")
if rcvamount.isdefined and self.isdefined:
print ("\tdefined values", str(self.value), ":", str(rcvamount.value))
# super() is magical with operator intercepts?
sumamount.value = self.value + rcvamount.value
else:
assert False, "cannot add undefined values"
return (sumamount)
#
### testfoo.py
import sys
from decimal import Decimal,getcontext
import socket
import operator
import re
import FOO
# set the class currency type
Factory = FOO.Amount()
print ("Amounts: ")
m0 = Factory.newamount(0.1)
m1 = Factory.newamount(0.02)
m2 = Factory.newamount(0.03)
print ("REPORT: ", m0.__class__, type(m0).__name__, hex(id(m0)), m0)
print ("REPORT: ", m1.__class__, type(m1).__name__, hex(id(m0)), m1)
print ("REPORT: ", m2.__class__, type(m2).__name__, hex(id(m0)), m2)
m3 = m2 + m1
print (type(m3).__name__, hex(id(m3)), m3)
print (m1,":", m2)
print (m1,":",m2,":",m3)
#
class: Amount
baseclass: <class 'decimal.Decimal'>
instance: 0x7f821c830ca8
postinitclass: Amount
postinitbaseclass: <class 'decimal.Decimal'>
postinitinstance: 0x7f821c830ca8
Amounts:
self: 0x7f821c830ca8
copy: 0x7f821c830ca8
setting from: float
self: 0x7f821c830ca8
copy: 0x7f821c830ca8
setting from: float
self: 0x7f821c830ca8
copy: 0x7f821c830ca8
setting from: float
REPORT: <class 'FOO.Amount'> Amount 0x7f821c830ca8 0
REPORT: <class 'FOO.Amount'> Amount 0x7f821c830ca8 0
REPORT: <class 'FOO.Amount'> Amount 0x7f821c830ca8 0
self: 0x7f821c830ca8
copy: 0x7f821c830ca8
setting from: Amount
self: 0x7f821c830ca8
copy: 0x7f821c830ca8
ADDING:
defined values 0 : 0
Amount 0x7f821c830ca8 0
0 : 0
0 : 0 : 0
__deepcopy__method to customize how deepcopy works with your class. See an example here