英文:
Way to use typehints to distinguish coordinate frames using numpy
问题
我正在开发一个处理不同坐标系的Python库。由于混淆的坐标系给我带来了一些问题,我想要在我的代码中更加有序。为此,我想要为坐标分配类型提示,并使用Mypy来检查它们。我的当前方法是
from typing import NewType, cast
import numpy as np
import numpy.typing as npt
frameA = NewType('frameA', npt.NDArray)
frameB = NewType('frameB', npt.NDArray)
def f(x_A : frameA) -> frameB:
# 做一些从frame A到frame B的操作
x_B = - x_A
return cast(frameB, x_B)
# 应该工作
x_A : frameA = np.random.rand(3,2)
x_B = f(x_A)
# 应该引发错误
x_B : frameB = np.random.rand(3,2)
x_A = f(x_B)
确实,Mypy能够检测到f
的输入是否在正确的坐标系中。然而,让我困扰的是,定义x_A : frameA = np.random.rand(3,2)
也会引发错误,因为np.random.rand(3,2)
的类型是ndarray[Any, dtype[floating[_64Bit]]]
,为了将其转换为frameA
,我必须进行类型转换。
是否有更好的方法来做到这一点,而不需要每次生成新变量时都进行类型转换?例如,有没有办法像这样做会更好:
x_A : frameA = np.random.rand((3,2), type=frameA)
<details>
<summary>英文:</summary>
I'm working on a python library dealing with coordinates in different frames. As I had quite some issues with confused frames, I'd like to bring more order into my code.
For this purpose, I want to assign typehints to coordinates and use Mypy to check them. My current approach is
from typing import NewType, cast
import numpy as np
import numpy.typing as npt
frameA = NewType('frameA', npt.NDArray)
frameB = NewType('frameB', npt.NDArray)
def f(x_A : frameA) -> frameB:
# do something to get from frame A to frameB
x_B = - x_A
return cast(frameB, x_B)
should work
x_A : frameA = np.random.rand(3,2)
x_B = f(x_A)
should throw error
x_B : frameB = np.random.rand(3,2)
x_A = f(x_B)
Indeed, Mypy is able to detect if the input of `f` is in the correct coordinate frame. What bothers my however, is that the definition `x_A : frameA = np.random.rand(3,2)` throws an error as well, because `np.random.rand(3,2)` is of type `ndarray[Any, dtype[floating[_64Bit]]]` and to make it `frameA`, I have to cast it.
Is there any nicer way to do this without the need of casting the variables every time I generate new ones? F.e., It would be really nice to have something like
x_A : frameA = np.random.rand((3,2), type=frameA)
</details>
# 答案1
**得分**: 2
`frameA`不仅仅是`NDArray`的别名;它是一个完全不同的类型,其值是从`NDArray`类型的值中*创建的*(尽管是微不足道的\*)。
你需要写
x_A : frameA = frameA(np.random.rand(3,2))
与其他类型的组合一样,Python不会仅仅因为可以将`np.random.rand(3, 2)`返回的值转换成`frame`类型的值而隐式地进行转换或构建。
---
\* 在运行时,`frameA`实际上只是简单地返回其参数的值,因此从这个意义上说,`frameA`和`NDArray`值共享相同的运行时表示。
<details>
<summary>英文:</summary>
`frameA` is not just an alias for `NDArray`; it is an entirely distinct type whose values are *created from* (albeit trivially\*) values of type `NDArray`.
You need to write
x_A : frameA = frameA(np.random.rand(3,2))
Like any other combinations of types, Python will not simply cast or otherwise construct a value of type `frame` implicitly just because it's *possible* to convert the value returned by `np.random.rand(3, 2)`.
---
\* At runtime, `frameA` really does simply return the value of its argument unchanged, so in that sense `frameA` and `NDArray` values share the same runtime representation.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论