PyCharm 表示未填充的参数,即使所有参数都是可选的
Posted
技术标签:
【中文标题】PyCharm 表示未填充的参数,即使所有参数都是可选的【英文标题】:PyCharm says unfilled parameters even though all parameters are optional 【发布时间】:2021-11-23 05:34:27 【问题描述】:我有一个函数应该接收另一个函数作为参数。我将该参数注释定义为:
input_function: Callable[
[
Optional[InputType],
Optional[Sequence[str]],
Optional[bool]
],
Awaitable[str]
] = func
与此同时,我的 func
函数是这样定义的:
async def func(input_type: InputType = None, formats: Sequence[str] = (), *, hide: bool = False) -> str: ...
函数签名和参数注解应该相同。但是,当我只用一个参数调用该函数时(因为所有参数都是可选的),PyCharm 说有未填充的参数:
【问题讨论】:
【参考方案1】:TLDR:将签名定义为带有__call__
的Protocol
,而不是Callable
。
from typing import Protocol
class InputFunction(Protocol):
async def __call__(self, input_type: InputType = None, formats: Sequence[str] = (), *, hide: bool = False) -> str: ...
input_function: InputFunction = func
Callable
类型只能表达一种有限的签名:显式位置参数,例如 Callable[[A, B], R]
或任意参数,例如 Callable[..., R]
。将其参数之一键入为Optional[T]
意味着它必须是“a T
或None
”,而不是可以省略。
相比之下,Protocol
的 __call__
方法允许使用常规定义语法定义签名,包括其所有功能,例如默认值。
Callback Protocols
协议可用于定义使用
Callable[...]
语法难以(甚至不可能)表达的灵活回调类型,例如可变参数、重载和复杂的泛型回调。它们是用一个特殊的__call__
成员定义的:
虽然Protocol
是一个类,但它在结构上匹配:仅使用__call__
方法定义它只是编码“具有相同签名的可调用对象”,并且具有相同签名的函数也满足这一点。
注意self
参数在__call__
定义中是必需的,但不用于检查签名是否匹配。
【讨论】:
您似乎实现了func
而不是__call__
。这是一个错误还是应该是这样的?
@Jonathan1609 哎呀。那确实是一个错误。固定。
好吧,我一到电脑就会标记这个答案。谢谢!
这不起作用,因为我不希望 PyCharm 告诉最终用户他的函数应该是 InputFunction
的一个实例。我希望 Pycharm 告诉他使用适合 __call__
中签名的函数。照片:imgur.com/p969BRC.png
你能看看它,看看有什么问题吗?【参考方案2】:
The documentation for typing.Optional 状态:
请注意,这与可选参数的概念不同,可选参数具有默认值。
the documentation for typing.Callable 表示:
没有指示可选或关键字参数的语法
因此,无法按照您想要的方式准确定义函数的类型。
【讨论】:
你的第一点是正确的,你的第二点是不正确的。您正确地指出typing.Optional
并不意味着 OP 似乎认为它确实如此,这是非常有用的信息。不幸的是,您的第二点是不正确的——是可以准确定义指示可选或关键字参数的函数。做到这一点的方法是使用回调协议,正如@MisterMiyagi 在他的回答中所说的那样,正如 MyPy 文档 mypy.readthedocs.io/en/stable/protocols.html#callback-protocols 所建议的那样以上是关于PyCharm 表示未填充的参数,即使所有参数都是可选的的主要内容,如果未能解决你的问题,请参考以下文章