我已经阅读了很多关于泛型类的知识,虽然这些很酷,但有时候,我只需要一个通用函数。这是我写的一小部分:
def _matrix_map(self, mapper):
"""returns the matrix applying the mapper funcfunc"""
return {key: mapper(value) for key, value in self._matrix.items()}
这应该如何为类型注释。在具有通用支持的静态类型语言中,我写这样的东西
private Dictionary<KeyType, ValueType> matrix;
private Dictionary<KeyType, T> matrix_map<T>(Func<ValueType, T>)
所以,我以为我会这样写:
T = TypeVar('T')
def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]:
我得到了像这样的mypy,但是pylint讨厌这个。
在第一行:
C0103:Invalid class attribute name "T"
在第二行:
E0602:Undefined variable 'T'
所以我觉得我做错了什么,我可以更改变量名称(ttt
?typ
?),但这不会解决第二个问题。我不能成为第一个想要(静态类型)通用功能的人,但我无法在任何地方找到任何好的资源。有什么建议吗?
答案 0 :(得分:1)
我猜你写的代码大概是这样的?
class Matrix:
T = TypeVar('T')
def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]:
# ...snip...
在运行时/ mypy实际上没有问题,但似乎pylint不满意你把“T”放在类定义的范围内。你可以做些什么来满足pylint是这样做:
T = TypeVar('T')
class Matrix:
def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]:
# ...snip...
这与以前的代码片段完全相同,并且还会满足pylint。
(作为一个切线,我认为pylint对前者不满意的事实实际上是一个错误。但是,尽管如此,关于类型提示的最佳实践还没有确定的风格指南/将一个typevar放在嵌套范围内是一个有点不常见的用例,所以我想我不能责怪他们不考虑这种情况。)
唯一的缺点是在外面使用TypeVar确实看起来模糊不清/好像它会污染全局命名空间。您可以通过将其重命名为_T
之类的内容来部分缓解此问题,以表明它是私有的。每当需要另一个泛型类或函数时,您也可以重用此类型变量,这也有助于防止命名空间污染。
有关将泛型与Python类型提示一起使用的更多信息,请参阅http://mypy.readthedocs.io/en/stable/generics.html