attrgetter函数可以根据您给它的参数返回不同的类型。如果您通过一个项目传递一个可迭代对象,它将仅返回对象的给定字段;如果你将一个包含多个项目的迭代传递给它,它会返回一个对象的这些字段的元组。
但是,当使用类型提示 + MyPy 时,MyPy 不会发现这种差异(它不会引发错误):
from operator import attrgetter
class OneThing:
foobar = "hello"
fields = ['foobar']
class TwoThings:
foobar = "hello"
goodbye = "potatoes"
fields = ['foobar', 'goodbye']
def attrgettertest(thing) -> tuple:
return attrgetter(*thing.fields)(thing)
def main():
onething = OneThing()
twothings = TwoThings()
t1 = attrgettertest(onething)
t2 = attrgettertest(twothings)
print("Attrgettertest on 'onething' returned {} with type {}".format(
t1, type(t1)))
print("Attrgettertest on 'twothings' returned {} with type {}".format(
t2, type(t2)))
if __name__ == "__main__":
main()
和输出:
$ python attrgettrtest.py
Attrgettertest on 'onething' returned hello with type <class 'str'>
Attrgettertest on 'twothings' returned ('hello', 'potatoes') with type <class 'tuple'>
$ mypy attrgettrtest.py
$
预期的结果将是这样的:
import random
def test() -> tuple:
if random.choice([0, 1]):
return ("foo", "bar")
return "foo"
if __name__ == "__main__":
for n in range(20):
print(test())
$ mypy test.py
test.py:8: error: Incompatible return value type (got "str", expected Tuple[Any, ...])
这是 MyPy 中的错误吗?