astropy:如何检查参数是否具有正确的单位

astropy: How can I check that an argument has the correct unit

在 Python 的 astropy 中,我如何检查函数的参数不仅有正确的单位,而且有一个单位?

我熟悉 is_equivalent(),所以要检查 M 是否有质量单位,我可以说

assert M.unit.is_equivalent(u.g)

其中 returns True 如果 M = 1e12 * u.Msun。但是如果 M 根本没有任何单位——例如如果我不小心超过了 M = 1e12 — 我会得到

AttributeError: 'Quantity' object has no '_normalize_equivalencies' member

一种方法是先将 M 乘以例如(u.m/u.m),它等于 Unit(dimensionless),如果它 有一个单位,它不会改变 M,而它会转换一个数字,如 [=23] =] 到 <Quantity 1.e+12> 然后可以在不给出错误的情况下进行检查。

不过,这似乎不是正确的方法。有没有更好的方法?

如评论中所述,如果您的目标是专门检查函数参数的单位,则可以使用专门用于此目的的 quantity_input 实用装饰器(并将引发 ValueErrorTypeErrorUnitsError 视情况而定,对于无效函数参数,它们通常比裸 AssertionError).

更合适

我特别喜欢 Python 3 特定的语法,它使用函数注释。以下是一些示例:

>>> from astropy import units as u
>>> @u.quantity_input
... def my_function(M: u.g):
...     print(M)

正确的单位:

>>> my_function(1e12*u.Msun)                                                
1000000000000.0 solMass
>>> my_function(1e12*u.g)                                                   
1000000000000.0 g

参数不正确的示例:

>>> my_function(1e12)
Traceback (most recent call last)
...
TypeError: Argument 'M' to function 'my_function' has no 'unit' attribute. You may want to pass in an astropy Quantity instead.
>>> my_function(1e12*u.dimensionless_unscaled)
Traceback (most recent call last)
...
UnitsError: Argument 'M' to function 'my_function' must be in units convertible to 'g'.

如果您有许多函数以 M 作为必须具有质量单位的参数,您也可以为它创建一个 shorthand,例如:

>>> M_mass = u.quantity_input(M=u.g)
>>> @M_mass
... def my_function(M):
...     print(M)

相同的方法可以用于不同单元的多个参数的函数。