【问题标题】:Type a function with a callable [duplicate]键入一个可调用的函数[重复]
【发布时间】:2021-09-03 02:24:47
【问题描述】:

我有很多具有相同签名的函数,比如说(int, int) -> int

有没有办法用Callable(或其他东西)键入这些函数,以避免为每个函数指定参数类型和返回类型?我想做这样的事情(但显然失败了):

from typing import Callable

f: Callable[[int, int], int]
def f(x, y):  #  with the previous line, this is equivalent to 'def f(x: int, y: int) -> int:'
    ...

运行 mypy 会导致:

file.py:4: error: Name "f" already defined on line 3
Found 1 error in 1 file (checked 1 source file)

【问题讨论】:

  • 是的,确实如此。谢谢你。使用您的装饰器解决方案mypy --strict 仍然会在装饰功能上抱怨Function is missing a type annotation,但我想没有解决方案(除了禁用该行的类型检查)。
  • @MisterMiyagi:但是使用你的装饰器,mypy 无法猜测装饰函数中的参数类型,还是我错了?在您的示例中,如果我在 any_greet_person 中执行 x: int = name,mypy 不会抱怨。据我了解,只有装饰器的定义 (def copy_signature(template: C) -> Callable[[C], C]:) 有助于 mypy 猜测 any_greet_person 的类型是 (name: str, age: int) -> str 但这只是 outside any_greet_person,不是是吗?
  • 确实,使用my answer 中显示的方法,函数的“内部”保持无类型。虽然我不知道解决方案(实际上我认为这是不可能改变的),但你是正确的,它与你想要的行为明显不同。
  • @MisterMiyagi:好的,感谢您的明确回答。最后一件事:做setattr(target, "__annotations__", getattr(template, "__annotations__")) 有什么意义,是为了动态类型检查吗?因为据我了解,mypy 并不关心这个,对吧?

标签: python type-hinting mypy python-typing


【解决方案1】:

也许有更优雅的解决方案。不推荐,但您可以设置<function>.__annotations__。有关它的更多信息here

from typing import get_type_hints

callable_int_annotations = {"x": int, "y": int, "return": int}

def f_with_hint(x: int, y: int) -> int:
    return x + y

def f_without_hint(x, y):
    return x + y

print(f"Before {get_type_hints(f_with_hint)=}")
print(f"Before {get_type_hints(f_without_hint)=}")

f_without_hint.__annotations__ = callable_int_annotations

print(f"After {get_type_hints(f_with_hint)=}")
print(f"After {get_type_hints(f_without_hint)=}")
Before get_type_hints(f_with_hint)={'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
Before get_type_hints(f_without_hint)={}
After get_type_hints(f_with_hint)={'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
After get_type_hints(f_without_hint)={'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}

【讨论】:

  • 请注意,这仅管理 runtime 注释。问题中使用的像 mypy 这样的静态类型检查器不会“看到”这些。
  • 感谢您的建议。我不知道__annotations__ 属性。然而,我的主要目标确实是让 mypy 对函数的定义感到满意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 2016-04-22
  • 1970-01-01
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多