python

时间:2017-12-03 05:11:34

标签: python pylint mypy

我已经阅读了很多关于泛型类的知识,虽然这些很酷,但有时候,我只需要一个通用函数。这是我写的一小部分:

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'

所以我觉得我做错了什么,我可以更改变量名称(ttttyp?),但这不会解决第二个问题。我不能成为第一个想要(静态类型)通用功能的人,但我无法在任何地方找到任何好的资源。有什么建议吗?

1 个答案:

答案 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