标签: python-typing

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
查看次数

如何编写一个满足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
查看次数

如何在 Python 中对对象的属性执行类型保护

PEP 647引入了类型防护来使用函数执行复杂的类型缩小操作。如果我有一个属性可以具有各种类型的类,是否有一种方法可以对作为函数参数给出的对象的属性执行类似的类型缩小操作?

class MyClass:
    """
    If `a` is `None` then `b` is `str`
    """
    a: Optional[int]
    b: Optional[str]
    # Some other things

def someTypeGuard(my_obj: MyClass) -> ???:
    return my_obj.a is not None
Run Code Online (Sandbox Code Playgroud)

我想我可能有必要在类型提示中实现一些与方括号有关的东西,但我真的不知道从哪里开始。

python python-typing typeguards

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

python TypedDict 的可变参数泛型类型?

我想做这样的事情:

from typing import TypeVar, Generic, TypedDict

 T = TypeVar("T")

class Foo(Generic[T], TypedDict):
    bar: T
    ...

foo: Foo[int] = {"bar": 42}
Run Code Online (Sandbox Code Playgroud)

但这会产生类型错误(“不能同时从 TypedDict 和非 TypedDict 基类继承”)。

有什么方法可以达到这个结果吗?

python python-typing

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

我应该在 Python 3.9+ 中使用大写 L 列表进行类型提示吗?

在 Python 3.9+ 中,我可以编写list_of_integers: list[int],但我看到高级开发人员使用旧语法(即使在 Python 3.9 和 3.10 脚本中):

from typing import List

list_of_integers: List[int]
Run Code Online (Sandbox Code Playgroud)

这对于向后兼容性和明确性来说是否优越?

python python-typing

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

如何类型提示 __getattr__ 方法的返回类型?

我很好奇Python 3 中是否有一种方法可以提示__getattr__()Python 中方法的返回类型。

我有以下用于测试目的的虚拟代码:

class MyClass:

    def __getattr__(self, item: str) -> str:
        return 'test'

    def __getattribute__(self, item: str) -> str:
        return 'test'


c = MyClass()

print(c.hello, type(c.hello))  # test <class 'str'>
Run Code Online (Sandbox Code Playgroud)

不幸的是,Pycharm 无法解析hello上面的属性类型。我不确定,但我认为它目前是按Any类型处理的。

我还对上述代码提出了以下变体,但仍然无法使类型提示按预期工作:

from typing import Callable

ReturnsString = Callable[[], str]


class MyClass:

    my_test_fn: ReturnsString = lambda self: 'hello'
    __getattr__: ReturnsString = lambda self, _item: 'test'
    __getattribute__: ReturnsString


c = MyClass()

# type hinting works as expected - return type is `str` …
Run Code Online (Sandbox Code Playgroud)

python getattr python-3.x python-typing

11
推荐指数
0
解决办法
2708
查看次数

如何在Python类型提示中表达多重继承?

在Java C#中,泛型方法可以具有带约束的类型参数,以定义必须实现的接口。

static <T extends Iterable<Integer> & Comparable<Integer>> void test(T p) {

}
Run Code Online (Sandbox Code Playgroud)

在Python中,如果我想使用类型提示来指定变量必须继承类A和B,我该怎么做?我检查了输入模块,它只有一个Union,这意味着变量的类型可以是任何提示,而不能是所有提示。

创建一个继承A和B的新类C似乎是一个解决方案,但看起来很麻烦。

python python-typing

10
推荐指数
1
解决办法
673
查看次数

列表子类的 Python 类型

我希望能够定义列表子类的内容。该类将如下所示。

class A(list):
   def __init__(self):
      list.__init__(self)
Run Code Online (Sandbox Code Playgroud)

我想包括打字,以便发生以下情况。

import typing

class A(list: typing.List[str]):  # Maybe something like this
   def __init__(self):
      list.__init__(self)

>> a = A()
>> a.append("a")  # No typing error
>> a.append(1)  # Typing error
Run Code Online (Sandbox Code Playgroud)

python list subclass python-3.x python-typing

10
推荐指数
1
解决办法
2554
查看次数

如何将 python 类型注释添加到烧瓶全局上下文 g?

我有一个装饰器,可以将用户添加到 Flask 全局上下文 g:

class User:
    def __init__(self, user_data) -> None:
        self.username: str = user_data["username"]
        self.email: str = user_data["email"]

def login_required(f):
    @wraps(f)
    def wrap(*args, **kwargs):
        user_data = get_user_data()
        user = User(user_data)
        g.user = User(user_data)

        return f(*args, **kwargs)

    return wrap
Run Code Online (Sandbox Code Playgroud)

我希望在控制器中访问 g.user 时知道 g.user 的类型(用户)。我怎样才能做到这一点?(我正在使用pyright)

python flask mypy python-typing pyright

10
推荐指数
2
解决办法
1793
查看次数

描述枚举名称的字符串文字联合的类型表达式?

鉴于:

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3
Run Code Online (Sandbox Code Playgroud)

Foo是否存在这样的类型表达式:

Foo[Color] = Literal["RED", "GREEN", "BLUE"]
Run Code Online (Sandbox Code Playgroud)

python enums python-typing

10
推荐指数
2
解决办法
6804
查看次数