python - python 泛型函数的最佳实践

标签 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?),但这不能解决第二个问题问题。我不是第一个想要(静态类型)泛型函数的人,但我在任何地方都找不到任何好的资源。有什么建议吗?

最佳答案

我猜你写的代码大概是这样的?

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 之类的名称来部分缓解这种情况,以表明它是私有(private)的。您也可以在需要另一个泛型类或函数时重用此类型变量,这也有望帮助减少命名空间污染。

有关使用带有 Python 类型提示的泛型的更多信息,请参阅 http://mypy.readthedocs.io/en/stable/generics.html

关于python - python 泛型函数的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47615480/

相关文章:

python - Matplotlib 数据框图上缺少 X 轴标签

python - Visual Studio PyTools 从现有代码创建 Django 项目

python - Linux 上的 Pylint `--good-names` 语法

python - 为什么我会收到 pylint 错误 : Module 'socket' has no 'gethostname' member (no-member)?

python - 在 ruamel.yaml 中,如何发出带有文字字符串 "null"的 ScalarEvent ?

python - 将列表与 DataFrame 中的每条记录进行比较

python - 为 PyLint 输出着色?

python - 从另一个通用 lambda 参数推断通用 lambda 参数

python - 类型提示 : when to annotate

python - mypy 提示 attrs 类中的 TypedDict 具有不兼容的类型