标签: python-typing

Python 3.9 和 PEP 585 中的typing.Any - 标准集合中的类型提示泛型

我想了解是否typing仍然需要该软件包?

如果在 Python 3.8 中我这样做:

from typing import Any, Dict
my_dict = Dict[str, Any]
Run Code Online (Sandbox Code Playgroud)

现在,在通过 PEP 585 的 Python 3.9 中,现在首选使用集合的内置类型,因此:

from typing import Any
my_dict = dict[str, Any]
Run Code Online (Sandbox Code Playgroud)

我是否仍然需要使用typing.Any或者是否有一个我找不到的内置类型来替换它?

python type-hinting python-typing python-3.9

12
推荐指数
1
解决办法
4340
查看次数

我可以告诉 mypy 表达式不会返回可选值吗?

我有以下代码:

def extract_table_date(bucket_path: str) -> str:
    event_date = re.search(r"date=([^/]+)", bucket_path)
    return event_date.group(1)[0:10].replace("-", "")
Run Code Online (Sandbox Code Playgroud)

mypy 在最后一行抛出错误:

“Optional[Match[str]]”的“None”项没有属性“group”

我想我可以通过为 分配一个类型来解决这个问题event_date,我可以:

from typing import Match

def extract_table_date(bucket_path: str) -> str:
    event_date: Match = re.search(r"date=([^/]+)", bucket_path)
    return event_date.group(1)[0:10].replace("-", "")
Run Code Online (Sandbox Code Playgroud)

但 mypy 现在在函数的第一行抛出另一个错误:

赋值中的类型不兼容(表达式的类型为“Optional[Match[Any]]”,变量的类型为“Match[Any]”)

我真的不知道如何通知 mypy 结果不是可选的,但尽管如此,我还是遵循了可选类型和 None 类型的建议,添加了断言:

from typing import Match

def extract_table_date(bucket_path: str) -> str:
    assert bucket_path is not None
    event_date: Match = re.search(r"date=([^/]+)", bucket_path)
    return event_date.group(1)[0:10].replace("-", "")
Run Code Online (Sandbox Code Playgroud)

但 mypy 仍然引发相同的错误。

我尝试通过更改定义的类型来修复event_date

from typing import Match, …
Run Code Online (Sandbox Code Playgroud)

python mypy python-typing

12
推荐指数
1
解决办法
9280
查看次数

你如何在python中对一个类型进行别名?

在某些(主要是功能性)语言中,您可以执行以下操作:

type row = list(datum)
Run Code Online (Sandbox Code Playgroud)

要么

type row = [datum]
Run Code Online (Sandbox Code Playgroud)

这样我们就可以构建这样的东西:

type row = [datum]
type table = [row]
type database = [table]
Run Code Online (Sandbox Code Playgroud)

有没有办法在python中执行此操作?你可以使用类来完成它,但是python有很多功能方面,所以我想知道它是否可以更容易地完成.

python alias type-hinting python-typing

11
推荐指数
4
解决办法
5803
查看次数

在 Python 类型注释中排除类型

我写了以下函数:

def _clean_dict(d):
    return {k: v for k, v in d.items() if v is not None}
Run Code Online (Sandbox Code Playgroud)

我想为函数添加类型注释:

def _clean_dict(d: Dict[Any, Any]) -> Dict[Any, Any]:                           
    return {k: v for k, v in d.items() if v is not None}
Run Code Online (Sandbox Code Playgroud)

但是,我想明确定义返回的字典中的值不能为 None。

有没有办法说“Any类型,除了NoneType”或“每个可能的值但是None”?

python type-hinting python-3.x mypy python-typing

11
推荐指数
2
解决办法
1683
查看次数

Mypy 子类中更具体的参数

我想声明一个带有抽象方法的基类,该方法具有类型化参数,以便实现类可以为该参数指定更具体的类型,例如:

from abc import ABC, abstractmethod

class Job(ABC):
    pass

class EasyJob(Job):
    pass

class HardJob(Job):
    pass

class Worker(ABC):
    @abstractmethod
    def run(self, job: Job) -> None:
        raise NotImplementedError()

class EasyWorker(Worker):
    def run(self, job: EasyJob) -> None:
        pass

class HardWorker(Worker):
    def run(self, job: HardJob) -> None:
        pass
Run Code Online (Sandbox Code Playgroud)

然而,mypy 对此抱怨是可以理解的:

line 14: error: Argument 1 of "run" is incompatible with supertype "Worker"; supertype defines the argument type as "Job"
line 18: error: Argument 1 of "run" is incompatible with supertype "Worker"; supertype defines the …
Run Code Online (Sandbox Code Playgroud)

python type-hinting mypy python-typing

11
推荐指数
1
解决办法
763
查看次数

如何将自定义协议与 Callable 协议结合起来?

我有一个装饰器,它接受一个函数并返回具有一些附加属性的相同函数:

import functools
from typing import *


def decorator(func: Callable) -> Callable:
    func.attr1 = "spam"
    func.attr2 = "eggs"
    return func
Run Code Online (Sandbox Code Playgroud)

如何键入提示的返回值decorator?我希望类型提示传达两条信息:

  1. 返回值是一个 Callable
  2. 返回值具有属性attr1attr2

如果我写一个协议,

class CallableWithAttrs(Protocol):
    attr1: str
    attr2: str
Run Code Online (Sandbox Code Playgroud)

那我输了Callable。显然我不能让协议继承自Callable;

class CallableWithAttrs(Callable, Protocol):
    attr1: str
    attr2: str
Run Code Online (Sandbox Code Playgroud)

mypy 说:

error: Invalid base class "Callable"
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我只使用Callable,我会丢失有关添加属性的信息。



这在引入类型变量时可能更加复杂,即当装饰器必须返回与给定函数相同类型的可调用对象时func,正如 MisterMiyagi 在评论中指出的那样。

import functools
from typing import *

C = TypeVar('C', bound=Callable)


def decorator(func: C) -> C:
    func.attr1 = …
Run Code Online (Sandbox Code Playgroud)

python type-hinting python-typing

11
推荐指数
2
解决办法
811
查看次数

List 是否有协变可变版本?

我已经将我真正想要注释的代码简化为这个最小版本:

def print_it(numbers_or_nones):
    for i, number in enumerate(numbers_or_nones):
        if number is None:
            numbers_or_nones[i] = 0
            print("NOOOO")
        else:
            print(number)


numbers = [1, 2, 3, 4]
print_it(numbers)
Run Code Online (Sandbox Code Playgroud)

numbers_or_nones我想对的参数进行注释print_it。它需要...

  • ...元素所在的通用类型Optional[int]
  • ...可迭代
  • ...支持索引分配

对于这种情况,正确的类型是什么?请注意,无法更改 的类型numbers : List[int]。我能看到的唯一选择是使用typing.overload.

列表

最简单的事情是List[Optional[int]]。然而,这给出了:

error: Argument 1 to "print_it" has incompatible type "List[int]"; expected "List[Optional[int]]"
note: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance
note: Consider using "Sequence" instead, which is covariant
Run Code Online (Sandbox Code Playgroud)

顺序

Unsupported target for indexed assignment ("Sequence[Optional[int]]")
Run Code Online (Sandbox Code Playgroud)

可变序列 …

python python-typing

11
推荐指数
1
解决办法
4836
查看次数

python - 指定具有多个基数的类型(输入 AND 运算符)

我理解(如这个问题文档中所解释的)X or 的类型提示Y可以表示为:

Union[X,Y]
Run Code Online (Sandbox Code Playgroud)

但是如何表达X and Y的类型提示呢?当表达相关对象必须是 和 的子类时,这将很有XY

只要所有继承这两者XY事先已知的类,以下示例就可以工作:

class X: pass
class Y: pass
class A(X,Y): pass
class B(X,Y): pass

def some_function(arg: Union[A,B]): 
    pass
    # do stuff with arg that only depends on inherited members from X and Y
Run Code Online (Sandbox Code Playgroud)

但是如果另一个依赖于上面代码的包定义了:

class C(X,Y): pass
Run Code Online (Sandbox Code Playgroud)

Csome_function也将按设计工作。我正在寻找更好的类型提示来使用,而不是Union[X,Y]包含任何可能的子类XY

我理解解决方法可能是定义:

class XY(X,Y): pass
Run Code Online (Sandbox Code Playgroud)

然后将其用作基类和类型提示:

class A(XY): pass
class B(XY): …
Run Code Online (Sandbox Code Playgroud)

python python-typing

11
推荐指数
1
解决办法
2912
查看次数

类型错误:“numpy._DTypeMeta”对象不可订阅

我正在尝试输入ndarray像这样的 numpy 提示:

RGB = numpy.dtype[numpy.uint8]
ThreeD = tuple[int, int, int]

def load_images(paths: list[str]) -> tuple[list[numpy.ndarray[ThreeD, RGB]], list[str]]: ...
Run Code Online (Sandbox Code Playgroud)

但在我运行此命令的第一行时,出现以下错误:

RGB = numpy.dtype[numpy.uint8]
TypeError: 'numpy._DTypeMeta' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)

如何ndarray正确输入提示a?

python numpy type-hinting type-alias python-typing

11
推荐指数
3
解决办法
5万
查看次数

如何编写一个满足typing.TextIO的类似文件的类?

io例如,在编写实现类文件接口的类时,我们可以从模块继承抽象基类之一,如调整迭代器以使其行为类似于 Python 中的类文件对象TextIOBase中所示。

另一方面,在类型注释中,我们应该使用派生自typing.IO(例如TextIO)的类来表示此类对象,如文件或类文件对象的类型提示中所示?Union 中 io.TextIOBase 的类型检查问题

然而,这似乎并没有像我预期的那样工作:

import io
import sys
import typing

class MyIO(io.TextIOBase):
    def write(self, text: str):
        pass

def hello(f: typing.TextIO):
    f.write('hello')

hello(sys.stdout)             # type checks
hello(open('temp.txt', 'w'))  # type checks
hello(MyIO())                 # does not type check
Run Code Online (Sandbox Code Playgroud)

当在此代码上运行 mypy 时(使用 Python 3.7.3 和 mypy 0.910),我们得到

错误:“hello”的参数 1 具有不兼容的类型“MyIO”;预期“TextIO”

问题

如何MyIO编写该类,使其被接受为类型的函数参数typing.TextIO(而不仅仅是使用typing.cast(typing.TextIO, ...))?

失败的尝试

  1. typing.TextIO不能用作基类:

    使用时class MyIO(typing.TextIO)

    错误:无法使用抽象属性“__enter__”、“__exit__”、...和“writelines”实例化抽象类“MyIO”(抑制了 …

python type-hinting mypy python-typing

11
推荐指数
1
解决办法
8061
查看次数