pint 中无法识别体积到质量的转换
Volume to Mass transformation not recognized in pint
我正在尝试在需要在维度之间进行转换的情况下使用 pint,例如。液体盎司到克。
我转换所需的值在数据库中,并且会因各种物质而变化(例如,不同液体的不同密度),因此我使用 Context.add_transformation() 方法动态创建我的转换.这是我的测试程序:
#!/opt/env/upgrade/bin/python
import pint
ureg = pint.UnitRegistry()
c = pint.Context('ab')
def vtom(ureg, x):
# here I print some output just to see if this function is ever called
# and what arguments are passed. It is not being called.
print "vtom(%s, %s)" % (ureg, x)
# right now I just return the input, so it's 1:1. I know this is
# not right, I am just trying to get pint to find the transform and use it.
return x
c.add_transformation('[volume]', '[mass]', vtom)
ureg.add_context(c)
PQ = ureg.Quantity
# this works fine
a = PQ(1 * ureg.oz)
print '%s = %s' % (a, a.to('gram'))
b = PQ(10 * ureg.floz)
c = PQ(10 * ureg.gram)
# both these fail, see exception output below
print '%s = %s' % (c, c.to('floz'))
print '%s = %s' % (b, b.to('gram'))
输出:
1 ounce = 28.349523125 gram
Traceback (most recent call last):
File "./p.py", line 26, in <module>
print '%s = %s' % (b, b.to('gram'))
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/quantity.py", line 332, in to
magnitude = self._convert_magnitude_not_inplace(other, *contexts, **ctx_kwargs)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/quantity.py", line 300, in _convert_magnitude_not_inplace
return self._REGISTRY.convert(self._magnitude, self._units, other)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/registry.py", line 686, in convert
return self._convert(value, src, dst, inplace)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/registry.py", line 1214, in _convert
return super(ContextRegistry, self)._convert(value, src, dst, inplace)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/registry.py", line 937, in _convert
return super(NonMultiplicativeRegistry, self)._convert(value, src, dst, inplace)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/registry.py", line 708, in _convert
raise DimensionalityError(src, dst, src_dim, dst_dim)
pint.errors.DimensionalityError: Cannot convert from 'fluid_ounce' ([length] ** 3) to 'gram' ([mass])
pint 似乎没有找到我的转换。在单位文本文件(pint附带的默认文件)中,定义了'[volume] = [length] ** 3',因此它应该能够遍历图形并找到'[mass]' .. 大概我以为...
谢谢!
您似乎需要指定在调用 .to
时需要使用的上下文,因为您的上下文称为 'ab',您应该写成 c.to('floz', 'ab')
。这解决了为什么你的函数 vtom
没有被调用的问题。
看起来您还必须定义两个方向的转换:
#!/opt/env/upgrade/bin/python
import pint
ureg = pint.UnitRegistry()
c = pint.Context('ab')
def vtom(ureg, x):
print ("vtom(%s, %s)" % (ureg, x))
density = 0.9 * ureg.gram / ureg.ml
return x/density
def vtom2(ureg, x):
print ("vtom2(%s, %s)" % (ureg, x))
density = 0.9 * ureg.gram / ureg.ml
return x*density
c.add_transformation('[volume]', '[mass]', vtom2)
c.add_transformation('[mass]', '[volume]', vtom)
ureg.add_context(c)
#ureg.enable_contexts('ab')
PQ = ureg.Quantity
# this works fine
a = PQ(1 * ureg.oz)
print ('%s = %s' % (a, a.to('gram')))
b = PQ(10 * ureg.floz)
c = PQ(10 * ureg.gram)
# both these fail, see exception output below
print ('%s = %s' % (c, c.to('floz', 'ab')))
print ('%s = %s' % (b, b.to('gram','ab')))
(我猜你每个方向都需要不同的功能)。
输出
1 ounce = 28.349523125 gram
vtom(<pint.registry.UnitRegistry object at 0x0390CDB0>, 10 gram)
10 gram = 0.37571136335381117 fluid_ounce
vtom2(<pint.registry.UnitRegistry object at 0x0390CDB0>, 10 fluid_ounce)
10 fluid_ounce = 266.16176606249996 gram
编辑:
正如下面的评论中提到的,我认为最初的错误很可能是因为库对返回值进行了一些维度分析以检查它是否有意义,如果没有则引发错误。因此,例如,质量可以是密度乘以体积,但不能是体积乘以标量,因为那只是一个 bigger/smaller 体积,而不是质量。
我正在尝试在需要在维度之间进行转换的情况下使用 pint,例如。液体盎司到克。
我转换所需的值在数据库中,并且会因各种物质而变化(例如,不同液体的不同密度),因此我使用 Context.add_transformation() 方法动态创建我的转换.这是我的测试程序:
#!/opt/env/upgrade/bin/python
import pint
ureg = pint.UnitRegistry()
c = pint.Context('ab')
def vtom(ureg, x):
# here I print some output just to see if this function is ever called
# and what arguments are passed. It is not being called.
print "vtom(%s, %s)" % (ureg, x)
# right now I just return the input, so it's 1:1. I know this is
# not right, I am just trying to get pint to find the transform and use it.
return x
c.add_transformation('[volume]', '[mass]', vtom)
ureg.add_context(c)
PQ = ureg.Quantity
# this works fine
a = PQ(1 * ureg.oz)
print '%s = %s' % (a, a.to('gram'))
b = PQ(10 * ureg.floz)
c = PQ(10 * ureg.gram)
# both these fail, see exception output below
print '%s = %s' % (c, c.to('floz'))
print '%s = %s' % (b, b.to('gram'))
输出:
1 ounce = 28.349523125 gram
Traceback (most recent call last):
File "./p.py", line 26, in <module>
print '%s = %s' % (b, b.to('gram'))
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/quantity.py", line 332, in to
magnitude = self._convert_magnitude_not_inplace(other, *contexts, **ctx_kwargs)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/quantity.py", line 300, in _convert_magnitude_not_inplace
return self._REGISTRY.convert(self._magnitude, self._units, other)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/registry.py", line 686, in convert
return self._convert(value, src, dst, inplace)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/registry.py", line 1214, in _convert
return super(ContextRegistry, self)._convert(value, src, dst, inplace)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/registry.py", line 937, in _convert
return super(NonMultiplicativeRegistry, self)._convert(value, src, dst, inplace)
File "/opt/env/upgrade/local/lib/python2.7/site-packages/pint/registry.py", line 708, in _convert
raise DimensionalityError(src, dst, src_dim, dst_dim)
pint.errors.DimensionalityError: Cannot convert from 'fluid_ounce' ([length] ** 3) to 'gram' ([mass])
pint 似乎没有找到我的转换。在单位文本文件(pint附带的默认文件)中,定义了'[volume] = [length] ** 3',因此它应该能够遍历图形并找到'[mass]' .. 大概我以为...
谢谢!
您似乎需要指定在调用 .to
时需要使用的上下文,因为您的上下文称为 'ab',您应该写成 c.to('floz', 'ab')
。这解决了为什么你的函数 vtom
没有被调用的问题。
看起来您还必须定义两个方向的转换:
#!/opt/env/upgrade/bin/python
import pint
ureg = pint.UnitRegistry()
c = pint.Context('ab')
def vtom(ureg, x):
print ("vtom(%s, %s)" % (ureg, x))
density = 0.9 * ureg.gram / ureg.ml
return x/density
def vtom2(ureg, x):
print ("vtom2(%s, %s)" % (ureg, x))
density = 0.9 * ureg.gram / ureg.ml
return x*density
c.add_transformation('[volume]', '[mass]', vtom2)
c.add_transformation('[mass]', '[volume]', vtom)
ureg.add_context(c)
#ureg.enable_contexts('ab')
PQ = ureg.Quantity
# this works fine
a = PQ(1 * ureg.oz)
print ('%s = %s' % (a, a.to('gram')))
b = PQ(10 * ureg.floz)
c = PQ(10 * ureg.gram)
# both these fail, see exception output below
print ('%s = %s' % (c, c.to('floz', 'ab')))
print ('%s = %s' % (b, b.to('gram','ab')))
(我猜你每个方向都需要不同的功能)。
输出
1 ounce = 28.349523125 gram
vtom(<pint.registry.UnitRegistry object at 0x0390CDB0>, 10 gram)
10 gram = 0.37571136335381117 fluid_ounce
vtom2(<pint.registry.UnitRegistry object at 0x0390CDB0>, 10 fluid_ounce)
10 fluid_ounce = 266.16176606249996 gram
编辑: 正如下面的评论中提到的,我认为最初的错误很可能是因为库对返回值进行了一些维度分析以检查它是否有意义,如果没有则引发错误。因此,例如,质量可以是密度乘以体积,但不能是体积乘以标量,因为那只是一个 bigger/smaller 体积,而不是质量。