我有一个带有多个默认值的 kwargs 的函数。其中之一(在中间的某个地方)是控制返回类型的布尔切换。
\n我想为此方法创建两个重载,Literal[True/False]但保留默认值。
我的想法如下:
\nfrom 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"\nRun Code Online (Sandbox Code Playgroud)\n但 mypy 提出:
\n\n\n …错误:重载函数签名 1 和 2 与不兼容的返回类型重叠
\n
这个答案似乎不适用于泛型。在检查以下代码时,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) 我有一个装饰器,可以在不带参数或带参数的情况下调用(所有字符串):
\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\nRun Code Online (Sandbox Code Playgroud)\n尽管已阅读mypy 文档的相关部分,但我很难提供适当的类型提示,以便类型检查器能够正确验证装饰器的使用。
\n这是我到目前为止所尝试过的:
\nfrom 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) 假设我正在尝试为一个库函数编写类型提示,该函数为用户定义的类型注册反序列化器:用户应该提供一个类型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:
decode有没有一种方法可以类型提示此方法,强制返回 实例的约束,以便此示例因不返回type_而引发错误?可以完成这项工作的一件事是非协变等价物,它只接受确切的类对象而不是任何子类型,但我不确定Python中是否存在这样的东西。strintType[T]T
python typing higher-order-functions invariance python-typing
如何创建一个 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) 我有一组不相关的类(一些是导入的),它们都有一个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) 我有一个排序的链表
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) 我想为已知函数编写一个包装函数,例如
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- 参数吗?
假设我们为回调定义一个类型,如下所示:
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:)以避免显式注释工作?
我无法正确获得以下类型提示。能否请你帮忙?
# 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-typing ×10
python ×9
mypy ×3
typing ×2
generics ×1
invariance ×1
pylance ×1
pyright ×1
python-3.x ×1