为需要 kwargs 的 Callable 键入提示

问题描述 投票:0回答:3

我想做类似的事情

from typing import Callable


def a(foo: Callable[[int], None]):
    foo(b=5)

此代码有效,但会发出警告

Unexpected argument

定义为

def a(foo: Callable[[int], None]):
    foo(5)

正常工作,不会出现预期的警告。


如何将预期参数作为

kwarg
传递到函数中,而类型检查器不会生我的气?

python types type-hinting
3个回答
12
投票

你可以在这里使用“可调用协议”,所以:

import typing

class MyCallableType(typing.Protocol):
    def __call__(self, bar:int) -> None:
        ...

def a(foo: MyCallableType):
    foo(32)
    foo(bar=32)

现在,使用

mypy
测试上述内容:

jarrivillaga$ mypy --version
mypy 0.910
jarrivillaga$ mypy test.py
Success: no issues found in 1 source file

注意,这允许 mypy 捕获各种错误,例如参数名称错误的函数,或者如果我们希望

b
成为指定仅关键字栏参数的函数:

import typing

class MyCallableType(typing.Protocol):
    def __call__(self, b:int) -> None:
        ...

def a(foo: MyCallableType):
    foo(32)
    foo(b=32)

def bar(b: int) -> None:
    pass

def baz(*, b: int) -> None:
    pass

def bing(x: int) -> None:
    pass

a(bar)
a(baz)
a(bing)

mypy 会抱怨以下内容:

jarrivillaga$ mypy test.py
test.py:21: error: Argument 1 to "a" has incompatible type "Callable[[NamedArg(int, 'b')], None]"; expected "MyCallableType"
test.py:22: error: Argument 1 to "a" has incompatible type "Callable[[int], None]"; expected "MyCallableType"
Found 2 errors in 1 file (checked 1 source file)

9
投票

Callable
文档

没有语法来指示可选参数或关键字参数;此类函数类型很少用作回调类型。

但是他们也说

Callable[..., ReturnType]
(文字省略号)可用于键入提示,可调用函数采用任意数量的参数并返回
ReturnType

在这里申请,那就是

def a(foo: Callable[..., None]):

您将丢失

int
注释,但要么是接受警告,要么明确超越警告。


0
投票

解决此问题的另一种方法是使用 3.10+

typing.Concatenate
:

from pathlib import Path
from typing import Callable, Concatenate

# expects extraction dir as its first param and leave the door open for kwargs
ExtractionCallback = Callable[Concatenate[Path, ...], None]

# expects extraction dir, processing dir and kwargs
TransformationCallback = Callable[Concatenate[Path, Path, ...], None]

来源:https://docs.python.org/3/library/typing.html#typing.Concatenate

© www.soinside.com 2019 - 2024. All rights reserved.