标签: python-typing

对元组进行类型提示但又不会太冗长

有没有一种方法可以输入提示元素元组,而不必多次定义每个内部元素?

例子:

a = ((1, 2), (2, 3), (3, 4), (4, 5))

a: Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, int], Tuple[int, int]]
Run Code Online (Sandbox Code Playgroud)

我正在寻找看起来像这样的东西

a: Tuple[5*Tuple[int, int]]
Run Code Online (Sandbox Code Playgroud)

否则我的代码会变得非常冗长,以便指示类似的内容(包含 5 个 4 个整数的元组的元组)

python type-hinting python-typing

4
推荐指数
1
解决办法
1606
查看次数

对于具有“@”(矩阵乘法)的对象的 Python 类型提示

我有一个函数fun()接受 NumPy ArrayLike和“矩阵”,并返回 numpy 数组。

from numpy.typing import ArrayLike
import numpy as np

def fun(A, x: ArrayLike) -> np.ndarray:
    return (A @ x) ** 2 - 27.0
Run Code Online (Sandbox Code Playgroud)

type对于有业务的实体,正确的是什么@?请注意,fun()也可以接受scipy.sparse;也许更多。

python numpy type-hinting python-typing

4
推荐指数
1
解决办法
313
查看次数

Mypy 在 __init__ 覆盖中接受不兼容的类型

我有以下Foo基类,并且Bar继承自它:

class Foo:
    def __init__(self, x: int) -> None:
        self._x = x

    def do(self, x: int) -> None:
        pass


class Bar(Foo):
    pass
Run Code Online (Sandbox Code Playgroud)

如果我重写Foo.doin Bar,并将参数的类型更改x为不兼容的内容(即不比 更通用int),那么 Mypy 将返回错误 - 这当然是我所期望的。

class Bar(Foo):
    def do(self, x: str) -> None:
        pass
Run Code Online (Sandbox Code Playgroud)

错误:

test.py:10: error: Argument 1 of "do" is incompatible with supertype "Foo"; supertype defines the argument type as "int"
test.py:10: note: This violates the Liskov substitution principle
test.py:10: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides …
Run Code Online (Sandbox Code Playgroud)

python types liskov-substitution-principle mypy python-typing

4
推荐指数
1
解决办法
1111
查看次数

如何使用Python中元类插入的方法对类进行类型检查?

在以下代码中some_method已通过元类添加:

from abc import ABC
from abc import ABCMeta
from typing import Type


def some_method(cls, x: str) -> str:
    return f"result {x}"


class MyMeta(ABCMeta):
    def __new__(mcs, *args, **kwargs):
        cls = super().__new__(mcs, *args, **kwargs)
        cls.some_method = classmethod(some_method)
        return cls


class MyABC(ABC):
    @classmethod
    def some_method(cls, x: str) -> str:
        return x


class MyClassWithSomeMethod(metaclass=MyMeta):
    pass


def call_some_method(cls: Type[MyClassWithSomeMethod]) -> str:
    return cls.some_method("A")


if __name__ == "__main__":
    mc = MyClassWithSomeMethod()
    assert isinstance(mc, MyClassWithSomeMethod)
    assert call_some_method(MyClassWithSomeMethod) == "result A"
Run Code Online (Sandbox Code Playgroud)

然而,MyPy对此很不满意:

minimal_example.py:27: error: …
Run Code Online (Sandbox Code Playgroud)

python metaclass type-hinting mypy python-typing

4
推荐指数
1
解决办法
2185
查看次数

子类的 Python 打字问题

这个问题是为了澄清我对 python 打字的疑问

from typing import Union

class ParentClass:
    parent_prop = 1

class ChildA(ParentClass):
    child_a_prop = 2

class ChildB(ParentClass):
    child_b_prop = 3

def method_body(val) -> ParentClass:
    if val:
        return ChildA()
    else:
        return ChildB()

def another_method() -> ChildA:
    return method_body(True)

print(another_method().child_a_prop)
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我使用的 linting 工具打印错误如下

error: Incompatible return value type (got "ParentClass", expected "ChildA")
Run Code Online (Sandbox Code Playgroud)

(我在哪里做method_body(True)

我还将method_body返回类型设置为 Union[ChildA, ChildB]. 这将导致error: Incompatible return value type (got "Union[ChildA, ChildB]", expected "ChildA")

我正在寻找更好的方法来做到这一点。如果有人知道解决方案,我们将非常感谢您的帮助。

python mypy python-typing

4
推荐指数
1
解决办法
1156
查看次数

类方法返回错误的类型提示 - 名称未定义?

下面的类有一个类方法create(),它作为返回类型的类型提示,用于创建该类的实例。

class X:
   @classmethod
   def create(cls) -> X:
     pass
Run Code Online (Sandbox Code Playgroud)

然而,却出现了以下错误?

名称错误:名称“X”未定义

python pylint python-typing

4
推荐指数
1
解决办法
2465
查看次数

Python 中的 Tuple[Hashable] 是什么意思?

我遇到了以下代码:

def func(self, v: Tuple[Hashable]):
...
Run Code Online (Sandbox Code Playgroud)

我知道v: Tuple这意味着变量 v 必须是 Tuple 类型,但这Tuple[Hashable]意味着什么?Python 中的元组不是总是可哈希的吗?

python type-hinting python-typing

4
推荐指数
1
解决办法
343
查看次数

为什么我们可以继承`typing.NamedTuple`?

Python 3.6之后,我们有了typing.NamedTuple,它是 的类型化版本collections.namedtuple(),我们可以像类一样继承它:

class Employee(NamedTuple):
    name: str
    id: int
Run Code Online (Sandbox Code Playgroud)

相比之下collections.namedtuple,这个语法更漂亮,但是我还是看不懂它的实现,无论是看typing.py文件,还是做一些简单的测试,我们都会发现它是一个函数而不是一个类:

# Python 3.10.6 typing.py
def NamedTuple(typename, fields=None, /, **kwargs):
    """..."""
    if fields is None:
        fields = kwargs.items()
    elif kwargs:
        raise TypeError("Either list of fields or keywords"
                        " can be provided to NamedTuple, not both")
    try:
        module = sys._getframe(1).f_globals.get('__name__', '__main__')
    except (AttributeError, ValueError):
        module = None
    return _make_nmtuple(typename, fields, module=module)
Run Code Online (Sandbox Code Playgroud)
>>> type(NamedTuple)
<class 'function'>
Run Code Online (Sandbox Code Playgroud)

我知道它使用了一些元类魔法,但我不明白使用时会发生什么class MyClass(NamedTuple)。为此,我尝试自定义一个函数来继承:

>>> def func_for_inherit(*args, **kwargs):
... …
Run Code Online (Sandbox Code Playgroud)

python namedtuple python-typing

4
推荐指数
1
解决办法
686
查看次数

我如何输入提示初始化参数与数据类中的字段相同?

假设我有一个自定义用例,我需要动态创建或定义__init__数据类的方法。

例如,假设我需要像这样装饰它,@dataclass(init=False)然后修改__init__()方法以采用关键字参数,例如**kwargs. 但是,在kwargs对象中,我仅检查已知数据类字段是否存在,并相应地设置这些属性(下面的示例)

我想向我的 IDE (PyCharm) 键入提示,修改后的内容__init__仅接受列出的数据类字段作为参数或关键字参数。我不确定是否有办法解决这个问题,使用typing库或其他方式。我知道 PY3.11 已计划进行数据类转换,这可能会也可能不会满足我的要求(我的直觉是否定的)。

这是我正在使用的示例代码,这是一个基本案例,说明了我遇到的问题:

from dataclasses import dataclass


# get value from input source (can be a file or anything else)
def get_value_from_src(_name: str, tp: type):
    return tp()  # dummy value


@dataclass
class MyClass:
    foo: str
    apple: int

    def __init__(self, **kwargs):
        for name, tp in self.__annotations__.items():
            if name in kwargs:
                value = kwargs[name]
            else:
                # here …
Run Code Online (Sandbox Code Playgroud)

python python-dataclasses python-typing

4
推荐指数
1
解决办法
1647
查看次数

预期类型“Iterable”(匹配泛型类型“Iterable[SupportsLessThanT]”)

@dataclass(frozen=True, eq=True, order=True)
class C:
    x: int

l = [C(1), C(2), C(1)]
print(sorted(l))
Run Code Online (Sandbox Code Playgroud)

上面的代码可以工作,但会发出警告: Expected type 'Iterable' (matched generic type 'Iterable[SupportsLessThanT]'), got 'list[C]' instead

我认为order=True传递给的参数@dataclass应该导致生成__lt__等,从而确认SupportsLessThanT

显式实现可以__lt__使警告静音,但是如果不这样做,我该如何使其静音呢?

python python-typing

4
推荐指数
1
解决办法
2356
查看次数