为什么 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()
、values
、items()
已经定义了)。
关于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
,而不是 Any
。 Any
完全是 loosey-goosey;它可以表示任何类型或任何类型的任何子类型。所以要明确地说“这个值真的可以是 any 类型”,你可以使用所有对象的祖先:object
。这在此处的文档中有所介绍:Dynamically typed code(尤其是 § Any vs. object)。
P.S。我对类型理论还很陌生,所以对此持保留态度。如果我有任何错误,非常感谢任何反馈。我只是回答,因为现有的答案不包括 为什么 错误发生或如何实际修复它而不是仅仅忽略它。
我有一个 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()
、values
、items()
已经定义了)。
关于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
,而不是 Any
。 Any
完全是 loosey-goosey;它可以表示任何类型或任何类型的任何子类型。所以要明确地说“这个值真的可以是 any 类型”,你可以使用所有对象的祖先:object
。这在此处的文档中有所介绍:Dynamically typed code(尤其是 § Any vs. object)。
P.S。我对类型理论还很陌生,所以对此持保留态度。如果我有任何错误,非常感谢任何反馈。我只是回答,因为现有的答案不包括 为什么 错误发生或如何实际修复它而不是仅仅忽略它。