为什么 mypy 抱怨 Any as return 注释,我应该如何注释可以是任何东西的 return 值?

Why does mypy complain about Any as return annotation and how should I annotate a return value that can be anything?

我有一个 class 本质上是字典的包装器:

class Wrapper(dict):

    ...

    def __getitem__(self, item: Hashable) -> Any:
        return self.wrapped[item]

检查带有 mypy 的注释时,检查此代码时会产生 Explicit "Any" is not allowed。我的猜测是,这源于 Any 是所有其他类型的祖先和继承者的概念。我应该如何在允许返回任何内容的地方注释此类函数?

当配置文件中该模块的 disallow_any_explicit 设置为 True 时会发生这种情况。只需删除默认选项 False.

您在问题中提供的信息不足以重现此错误,但如果您唯一的问题是:

How should I annotate such function where I want to allow anything to be returned?

简单的答案是根本不要注释它。默认情况下它将充当 Any.

如果你真的需要自定义映射(是吗?)我建议不要继承 dict 因为它会在未来造成很多痛苦(你应该重新定义它的方法或有时您会使用 self.wrapped,有时则不会。

我们可以简单地使用 collections.abc module 中的 MutableMapping ABC 并定义基本方法(如 __getitem__),其余的(keys()valuesitems() 已经定义了)。

关于mypy:我更喜欢为elements/keys/values/etc定义辅助类型变量。 class.

里面

所以我们可以得到类似

的结果
from collections import abc
from typing import (Dict,
                    Iterator,
                    TypeVar)


class Wrapper(abc.MutableMapping):
    KeyType = TypeVar('KeyType')
    ValueType = TypeVar('ValueType')

    def __init__(self, wrapped: Dict[KeyType, ValueType]) -> None:
        self.wrapped = wrapped

    def __delitem__(self, key: KeyType) -> None:
        del self.wrapped[key]

    def __len__(self) -> int:
        return len(self.wrapped)

    def __iter__(self) -> Iterator[KeyType]:
        return iter(self.wrapped)

    def __setitem__(self, key: KeyType, value: ValueType) -> None:
        self.wrapped[key] = value

    def __getitem__(self, key: KeyType) -> ValueType:
        return self.wrapped[key]

测试

运行 mypy with --disallow-any-explicit flag 导致没有 errors/warnings.

该案例的正确注释是 object,而不是 AnyAny 完全是 loosey-goosey;它可以表示任何类型或任何类型的任何子类型。所以要明确地说“这个值真的可以是 any 类型”,你可以使用所有对象的祖先:object。这在此处的文档中有所介绍:Dynamically typed code(尤其是 § Any vs. object)。

P.S。我对类型理论还很陌生,所以对此持保留态度。如果我有任何错误,非常感谢任何反馈。我只是回答,因为现有的答案不包括 为什么 错误发生或如何实际修复它而不是仅仅忽略它。