标签: python-typing

PEP 585 在 Python 3.7 和 3.8 下在运行时不可用吗?

PEP 585 —— 标准集合中的类型提示泛型声称在 Python 3.7 和 3.8 下都具有标准from __future__ import annotations序言的可用性。尤其:

对于仅限于类型注释的用例,带有annotationsfuture-import(自 Python 3.7 起可用)的Python 文件可以参数化标准集合,包括内置函数。

从 Python 3.7 开始,from __future__ import annotations使用时,函数和变量注释可以直接参数化标准集合。例子:

from __future__ import annotations

def find(haystack: dict[str, list[int]]) -> int:
    ...
Run Code Online (Sandbox Code Playgroud)

虽然上面的玩具示例技术上进行了解析,但仅此而已。在 Python 3.7 或 3.8 下尝试在运行时实际使用参数化的内置集合总是会引发可怕的TypeError: 'type' object is not subscriptable异常:

>>> def find(haystack: dict[str, list[int]]) -> int: pass
>>> print(find.__annotations__)
{'haystack': 'dict[str, list[int]]', 'return': 'int'}
>>> eval(find.__annotations__['haystack'])
TypeError: 'type' object is not subscriptable …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-typing pep585

13
推荐指数
1
解决办法
988
查看次数

如何在 FastAPI 主体验证中使用可区分的联合类型?(模型上的联盟)

我从 Typescript 中知道了一个概念,称为“受歧视的联合”。这是你放置 2 个结构体(类等)的地方,并且类型是根据结构体的值决定的。我正在尝试通过Pydantic验证在FastAPI中实现类似的目标。我可以收到两种不同的请求负载。是其中之一还是另一个取决于变量。如果是,则应由 验证,如果是,则应由 验证。我该如何实现这一目标?找不到任何其他解决方案。accountTypecreativeRegistrationPayloadCreativebrandRegistrationPayloadBrand

问题是它要么返回

unexpected value; permitted: 'creative' (type=value_error.const; given=brand; permitted=('creative',))

或者它根本不起作用。

class RegistrationPayloadBase(BaseModel):
    first_name: str
    last_name: str
    email: str
    password: str


class RegistrationPayloadCreative(RegistrationPayloadBase):
    accountType: Literal['creative']


class RegistrationPayloadBrand(RegistrationPayloadBase):
    company: str
    phone: str
    vat: str
    accountType: Literal['brand']

class A(BaseModel):
    b: Union[RegistrationPayloadBrand, RegistrationPayloadCreative]

def main():
    A(b={'first_name': 'sdf', 'last_name': 'sdf', 'email': 'sdf', 'password': 'sdfds', 'accountType': 'brand'})

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

python validation python-typing pydantic fastapi

13
推荐指数
2
解决办法
1万
查看次数

即使我使用 TYPE_CHECKING 导入,也会出现注释的 NameError

我有两个带有注释/类型提示的类。

第一个工作没有任何问题:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from bunyamin.models.exchange import Exchange

class Kline:

    def read_klines(exchange: Exchange):
        pass
Run Code Online (Sandbox Code Playgroud)

第二个确实很相似:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from bunyamin.models.timeframe import Timeframe

def normalize_dt(dt: datetime, timeframe: Timeframe) -> datetime:  # -> This line raises NameError
    pass
Run Code Online (Sandbox Code Playgroud)

但提出NameError: name 'Timeframe' is not defined

我知道我可以使用字符串(如'Timeframe')而不是类本身,但据我所知这不是预期的行为。我缺少什么?

我使用的 Python 版本是 3.8.2(如果相关的话)。

编辑:

当我试图隔离问题时,我省略了所有“看似不相关”的导入。但第一个文件实际上包含from __future__ import annotations在顶部,这使得它可以工作。详情请参阅第一个答案。

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

13
推荐指数
2
解决办法
5033
查看次数

Python 打字:TypedDict 是否允许附加/额外的键?

是否typing.TypedDict允许额外的钥匙?如果某个值具有 TypedDict 定义中不存在的键,该值是否会通过类型检查器?

python mypy python-typing

13
推荐指数
1
解决办法
5828
查看次数

MyPy 中的相同类型如何不兼容?

使用以下示例:

from typing import Callable, Generic, Type, TypeVar

ThetaType = TypeVar('ThetaType', bound=int)
XType = TypeVar('XType', bound=int)


class IteratedFunction(Generic[ThetaType, XType]):

    def find_fixed_point(self,
                         theta: ThetaType,
                         x_init: XType) -> XType:
        return x_init


def combinator(
    iterated_function_cls: Type[
        IteratedFunction[ThetaType, XType]]) -> Callable[
            [IteratedFunction[ThetaType, XType]], XType]:
    old_find_fixed_point = iterated_function_cls.find_fixed_point

    def new_find_fixed_point(
            iterated_function: IteratedFunction[ThetaType, XType],
            theta: ThetaType,
            x_init: XType) -> XType:
        return old_find_fixed_point(iterated_function, theta, x_init)

    return new_find_fixed_point
Run Code Online (Sandbox Code Playgroud)

MyPy 说:

a.py:25: error: Incompatible return value type (got "XType", expected "XType")
a.py:25: error: Argument 1 has incompatible type "IteratedFunction[ThetaType, …
Run Code Online (Sandbox Code Playgroud)

python mypy python-typing

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

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

使用 python 类型提示时,Text 与 str

在键入注释字符串、文本或 str 时应该使用什么?使用时有什么区别?

例如:

from typing import Text
def spring(a: Text) -> Text:
    return a.upper()
Run Code Online (Sandbox Code Playgroud)

或者

def spring(a: str) -> str:
    return a.upper()
Run Code Online (Sandbox Code Playgroud)

python string annotations python-3.x python-typing

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

如何在Python中定义最终的classvar变量

正如您在PEP 526中看到的,我们可以使用 ClassVar 字定义静态变量类。像下面这样

class Starship:
    stats: ClassVar[dict[str, int]] = {} # class variable
    damage: int = 10                     # instance variable
Run Code Online (Sandbox Code Playgroud)

正如您在PEP 591中看到的另一个打字功能,我们可以使用 Final word 定义常量(只读)变量,如下所示

class Connection:
    TIMEOUT: Final[int] = 10
Run Code Online (Sandbox Code Playgroud)

我的问题是如何组合这两个词来表示我的类静态变量是 Final?

例如下面的代码有效吗?

class Connection:
    TIMEOUT: Final[ClassVar[int]] = 10
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-3.8 python-typing

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

我可以告诉 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
查看次数

为什么 mypy 很难分配给嵌套字典?

mypy版本0.910

考虑

d = {
    'a': 'a',
    'b': {
        'c': 1
    }
}

d['b']['d'] = 'b'
Run Code Online (Sandbox Code Playgroud)

将其提供给mypy结果

error: Unsupported target for indexed assignment ("Collection[str]")
Run Code Online (Sandbox Code Playgroud)

mypy放置推断错误类型的一侧d(它显然不是字符串集合),添加一个非常基本的显式类型d修复此问题:

d: dict = {
    ... # same as above
}
Run Code Online (Sandbox Code Playgroud)
Success: no issues found in 1 source file
Run Code Online (Sandbox Code Playgroud)

我觉得这很奇怪。mypy绝对应该能够推断出这d是一个没有d: dict.

python type-hinting mypy python-typing

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