标签: python-typing

如何使用多个可选参数来类型重载函数?

我有一个带有多个默认值的 kwargs 的函数。其中之一(在中间的某个地方)是控制返回类型的布尔切换。

\n

我想为此方法创建两个重载,Literal[True/False]但保留默认值。

\n

我的想法如下:

\n
from typing import overload, Literal\n\n@overload\ndef x(a: int = 5, t: Literal[True] = True, b: int = 5) -> int: ...\n\n@overload\ndef x(a: int = 5, t: Literal[False] = False, b: int = 5) -> str: ...\n\ndef x(a: int = 5, t: bool = True, b: int = 5) -> int | str:\n    if t:\n        return 5\n    return "asd"\n
Run Code Online (Sandbox Code Playgroud)\n

但 mypy 提出:

\n
\n

错误:重载函数签名 1 和 2 与不兼容的返回类型重叠

\n
\n …

python mypy python-typing

5
推荐指数
1
解决办法
1848
查看次数

mypy:如何在泛型类中声明返回 self 的方法的返回类型?

这个答案似乎不适用于泛型。在检查以下代码时,Mypy 抱怨“错误:缺少泛型类型 A 的类型参数”。我尝试使用'A[T]'TypeVar 但 mypy 说“错误:类型变量 T 未绑定。” 我还尝试使用AnyA[T]作为返回类型,get但会产生两个错误消息,即已知的“错误:缺少泛型类型 A 的类型参数”和新的错误消息“与参数一起使用的类型变量 AnyA”。

如何正确指定返回类型get

import typing

T = typing.TypeVar('T')
AnyA = typing.TypeVar('AnyA', bound='A')

class A(typing.Generic[T]):

    def __init__(self, val: T) -> None:
        self.val = val

    def get(self: AnyA) -> AnyA:
        return self

class B(A[T]):
    def is_int(self) -> bool:
        return isinstance(self.val, int)


if __name__ == '__main__':
    b = B(42)
    print(b.get().is_int())
Run Code Online (Sandbox Code Playgroud)

generics mypy python-typing

5
推荐指数
1
解决办法
2899
查看次数

可以带或不带参数使用的类型装饰器

我有一个装饰器,可以在不带参数或带参数的情况下调用(所有字符串):

\n
@decorator\ndef fct0(a: int, b: int) -> int:\n    return a * b\n\n\n@decorator("foo", "bar")  # any number of arguments\ndef fct1(a: int, b: int) -> int:\n    return a * b\n
Run Code Online (Sandbox Code Playgroud)\n

尽管已阅读mypy 文档的相关部分,但我很难提供适当的类型提示,以便类型检查器能够正确验证装饰器的使用。

\n

这是我到目前为止所尝试过的:

\n
from typing import overload, TypeVar, Any, Callable\n\nF = TypeVar("F", bound=Callable[..., Any])\n\n@overload\ndef decorator(arg: F) -> F:\n    ...\n\n@overload\ndef decorator(*args: str) -> Callable[[F], F]:\n    ...\n\ndef decorator(*args: Any) -> Any:\n    # python code adapted from https://stackoverflow.com/q/653368\n\n    # @decorator -> shorthand for @decorator()\n    if len(args) == 1 and callable(args[0]):\n …
Run Code Online (Sandbox Code Playgroud)

python python-decorators mypy python-typing pyright

5
推荐指数
1
解决办法
749
查看次数

是否存在非协变“Type[T]”?

假设我正在尝试为一个库函数编写类型提示,该函数为用户定义的类型注册反序列化器:用户应该提供一个类型T和一个函数decode: str -> T

我认为使用 python 的 PEP-484 类型提示编写此代码的最自然方法如下:

from typing import Callable, Type, TypeVar
T = TypeVar("T")
def register_decoder(type_: Type[T], decode: Callable[[str], T]):
    ...
Run Code Online (Sandbox Code Playgroud)

Type[T]对我来说不幸的是,协变的事实T意味着这对于解码函数来说不够严格:至少在 Pyright 中,register_decoder(int, decode=str)调用通过类型检查,类型变量T解析为 union int | str

Pyright 对 int|str 的推论

decode有没有一种方法可以类型提示此方法,强制返回 实例的约束,以便此示例因不返回type_而引发错误?可以完成这项工作的一件事是非协变等价物,它只接​​受确切的类对象而不是任何子类型,但我不确定Python中是否存在这样的东西。strintType[T]T

python typing higher-order-functions invariance python-typing

5
推荐指数
1
解决办法
392
查看次数

如何使用包含连字符的键定义 TypedDict 类

如何创建一个 TypedDict 类,该类支持包含连字符或字符串中支持的其他字符的键,例如下面示例中的“justify-content”。

from typing import TypedDict, Literal
from typing_extensions import NotRequired

class Attributes(TypedDict):
    width: NotRequired[str]
    height: NotRequired[str]
    direction: NotRequired[Literal["row", "column"]]
    justify-content: NotRequired[Literal["start", "end", "center", "equally-spaced"]]
Run Code Online (Sandbox Code Playgroud)

python typing python-typing

5
推荐指数
1
解决办法
1534
查看次数

类型提示返回子类的类装饰器

我有一组不相关的类(一些是导入的),它们都有一个a类型为 的公共属性(或属性) dict[str, Any]

其中akey 下应该有另一个字典"b",我想将其作为属性公开在任何这些类上b以简化inst.a.get("b", {})[some_key]inst.b[some_key]

我已将以下子类工厂用作本地类的类装饰器和导入类的函数。

但到目前为止,我未能cls正确键入提示其参数并返回值。

from functools import wraps

def access_b(cls):
    @wraps(cls, updated=())
    class Wrapper(cls):
        @property
        def b(self) -> dict[str, bool]:
            return self.a.get("b", {})
    return Wrapper
Run Code Online (Sandbox Code Playgroud)

我最近一次打字尝试的 MRE(有mypy 0.971错误):

from functools import wraps
from typing import Any, Protocol, TypeVar

class AProtocol(Protocol):
    a: dict[str, Any]

class BProtocol(AProtocol, Protocol):
    b: dict[str, bool]

T_a = TypeVar("T_a", bound=AProtocol)
T_b = TypeVar("T_b", bound=BProtocol)

def …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-decorators python-typing

5
推荐指数
1
解决办法
879
查看次数

Python中实现无继承的接口

我有一个排序的链表

class SortedLinkedList:
    # ...
    def insert(self, value: int):
        # ...
        if node.value > value:
            self.add_before(node, value)
        # ...
Run Code Online (Sandbox Code Playgroud)

我想将 a 可以保存的值类型概括为Node从仅s 到通过实现魔术方法int重载运算符的任何对象。>__gt__()

在其他语言中,我会通过使用 来实现这一点Interface,但 Python 显然没有类似的东西。我已经看到通过使用抽象类来伪造接口的建议,例如

class Sortable(ABC):
    @abstractmethod
    def __gt__(self, other) -> bool:
        pass

class SortedLinkedList:
    # ...
    def insert(self, value: Sortable, node: Node):
        # ...
Run Code Online (Sandbox Code Playgroud)

问题是这种方法需要扩展和使用 的子类,这意味着不能使用Sortable已经具有整数等功能的类型>

linkedlist.insert(5) # Pylance red squiggles
Run Code Online (Sandbox Code Playgroud)
Argument of type "Literal[5]" cannot be assigned to
parameter "value" of type "Sortable" in …
Run Code Online (Sandbox Code Playgroud)

python python-typing pylance

5
推荐指数
1
解决办法
334
查看次数

预定义函数的 ParamSpec,不使用通用 Callable[P]

我想为已知函数编写一个包装函数,例如

    def wrapper(*args, **kwargs)
         foo()
         return known_function(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

我如何添加类型注释wrapper,使其完全遵循类型注释known_function


我已经看过了ParamSpec,但它似乎只在包装函数是通用的并且将内部函数作为参数时才起作用。

    P = ParamSpec("P")
    T = TypeVar('T')
    def wrapper(func_arg_that_i_dont_want: Callable[P,T], *args: P.args, **kwargs: P.kwargs)
         foo()
         return known_function(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

我可以强制P只对 有效known_function,而不将其链接到Callable- 参数吗?

python python-typing

5
推荐指数
1
解决办法
1517
查看次数

我可以使用 Typing.Callable 类型自动注释函数吗?如何?

假设我们为回调定义一个类型,如下所示:

CallbackFn = Callable[[str, str, int, int], None]
Run Code Online (Sandbox Code Playgroud)

当我想要实现回调函数并使用外部工具对其进行类型检查时CallbackFn,我必须显式注释类型:

def my_callback(s1: str, s2: str, i1: int, i2: int) -> None:
  ...
Run Code Online (Sandbox Code Playgroud)

有什么方法可以使用定义的类型提示来CallbackFn注释函数(例如def my_callback(s1,s2,i1,i2) as CallbackFn:)以避免显式注释工作?

python python-typing

5
推荐指数
1
解决办法
1393
查看次数

对于这种情况(子类方法),正确的类型是什么?

我无法正确获得以下类型提示。能否请你帮忙?

# example edited to make simpler (was async)
from typing import Any, Callable, ClassVar

class Base:
    def n_a(self) -> str:
        return 'N/A'

    meth1: ClassVar[Callable[[Base], str]] = n_a 
    # also meth2, meth3, ...

class Subclass(Base):
    def meth1(self) -> str:  # <-- line 11
        return 'yes'
Run Code Online (Sandbox Code Playgroud)

错误是:

test.py:11: error: Signature of "meth1" incompatible with supertype "Base"  [override]
test.py:11: note:      Superclass:
test.py:11: note:          def (Base, /) -> str
test.py:11: note:      Subclass:
test.py:11: note:          def meth1(self) -> str
Run Code Online (Sandbox Code Playgroud)

问题大概就在这里:

ClassVar[Callable[[Base], str]]
                  ^^^^^^
Run Code Online (Sandbox Code Playgroud)

因为这是没有错误地接受的: …

python python-typing

5
推荐指数
1
解决办法
138
查看次数