I'm looking to roll my own simple object that can keep track of units for variables (maybe I'll be adding other attributes like tolerances too). Here is what I have so far:
class newVar():
def __init__(self,value=0.0,units='unknown'):
self.value=value
self.units=units
def __str__(self):
return str(self.value) + '(' + self.units + ')'
def __magicmethodIdontknow__(self):
return self.value
diameter=newVar(10.0,'m') #define diameter's value and units
print diameter #printing will print value followed by units
#intention is that I can still do ALL operations of the object
#and they will be performed on the self.value inside the object.
B=diameter*2
Because I don't have the right magic method i get the following output
10.0(m)
Traceback (most recent call last):
File "C:\Users\user\workspace\pineCar\src\sandBox.py", line 25, in <module>
B=diameter*2
TypeError: unsupported operand type(s) for *: 'instance' and 'int'
I guess i could override every magic method to just return self.value but that sounds wrong. Maybe I need a decorator?
Also, I know I can just call diameter.value but that seems repetative
I once tried to implement something similar myself, but never managed to finish it. One way is to implement a new class from scratch, which contains both the value and the units. But if you want to use it in calculations, you have to implement all the magic methods like __add__
and __mul__
. An alternative is to sub-class float itself:
class FloatWithUnit(float):
def __new__(cls, val, unit):
return float.__new__(cls, val)
def __init__(self, val, unit):
self.unit = unit
def __str__(self):
return '%g %s' % (self, self.unit)
def __repr__(self):
return self.__str__()
Subclassing float is apparently a bit tricky, so you have to implement __new__
in addition to __init__
, see here for more discussion. When entering such an object on the command line, it shows its units:
In [2]: g = FloatWithUnit(9.81, 'm/s^2')
In [3]: g
Out[3]: 9.81 m/s^2
In [4]: type(g)
Out[4]: __main__.FloatWithUnit
But when used in caluations, it behaves like a normal float
In [5]: g2 = 2 * g
In [6]: g2
Out[6]: 19.62
In [7]: type(g2)
Out[7]: float