Python – pint – Can I set default type to Decimal?
Question:
Im using pint module in a project. Objects in my project handle numerical data as Decimals. When I set simple pint units to a Decimal, it works:
>>> import pint
>>> from decimal import Decimal as D
>>> ureg = pint.UnitRegistry()
>>> D(10) * ureg.kN
<Quantity(10, 'kilonewton')>
But, if I try to add a second unit, it breaks. Building kiloNewton*meters in this example:
>>> D(10) * ureg.kN * ureg.m
TypeError: unsupported operand type(s) for *: 'decimal.Decimal' and 'float'
I’m using this hack:
>>> a = D(1) * ureg.kN
>>> b = D(1) * ureg.m
>>> unit_kNm = a * b
>>> D(10) * unit_kNm
<Quantity(10, 'kilonewton * meter')>
I understand why it happens. I’m looking for a solution to set up pint as I want.
Answers:
Type cast it to decimal
import decimal
D(10) * ureg.kN * decimal.Decimal(ureg.m)
This works:
>>> D(10) * (ureg.kN * ureg.m)
<Quantity(10, 'kilonewton * meter')>
And this too:
>>> Q = ureg.Quantity
>>> Q(D(10), "kN*m")
<Quantity(10, 'kilonewton * meter')>
As version 0.11 of pint
, you can create UnitRegistry
with the non_int_type=Decimal
options. All new quantities created with this UnitRegistry
instance have their value represented by a Decimal
instance.
Example:
import pint
from decimal import Decimal
ureg = pint.UnitRegistry(non_int_type=Decimal)
a = ureg.Quantity("5 meter")
print(type(a.magnitude))
This will show that the magnitude is of type <class 'decimal.Decimal'>
.
Im using pint module in a project. Objects in my project handle numerical data as Decimals. When I set simple pint units to a Decimal, it works:
>>> import pint
>>> from decimal import Decimal as D
>>> ureg = pint.UnitRegistry()
>>> D(10) * ureg.kN
<Quantity(10, 'kilonewton')>
But, if I try to add a second unit, it breaks. Building kiloNewton*meters in this example:
>>> D(10) * ureg.kN * ureg.m
TypeError: unsupported operand type(s) for *: 'decimal.Decimal' and 'float'
I’m using this hack:
>>> a = D(1) * ureg.kN
>>> b = D(1) * ureg.m
>>> unit_kNm = a * b
>>> D(10) * unit_kNm
<Quantity(10, 'kilonewton * meter')>
I understand why it happens. I’m looking for a solution to set up pint as I want.
Type cast it to decimal
import decimal
D(10) * ureg.kN * decimal.Decimal(ureg.m)
This works:
>>> D(10) * (ureg.kN * ureg.m)
<Quantity(10, 'kilonewton * meter')>
And this too:
>>> Q = ureg.Quantity
>>> Q(D(10), "kN*m")
<Quantity(10, 'kilonewton * meter')>
As version 0.11 of pint
, you can create UnitRegistry
with the non_int_type=Decimal
options. All new quantities created with this UnitRegistry
instance have their value represented by a Decimal
instance.
Example:
import pint
from decimal import Decimal
ureg = pint.UnitRegistry(non_int_type=Decimal)
a = ureg.Quantity("5 meter")
print(type(a.magnitude))
This will show that the magnitude is of type <class 'decimal.Decimal'>
.