如何向用户界提供类型的暗示?

发布于 2025-02-02 21:43:56 字数 1790 浏览 2 评论 0原文

我想定义一个userDict,该读取JSON的值并存储给定密钥的位置。 JSON文件看起来像这样:

{
    "pages": [
        {
            "areas": [
                {
                    "name": "My_Name",
                    "x": 179.95495495495493,
                    "y": 117.92792792792793,
                    "height": 15.315315315315303,
                    "width": 125.58558558558553
                },
                ...
              ]
        }
    ]
}

我想指出键入linter(例如mypy),该字典是字符串,值为position

我当前的代码如下:

import json
from collections import UserDict
from dataclasses import dataclass, field
from pathlib import Path
from typing import Dict, List, Optional, Union

from typing_extensions import Literal


JsonPosition = Dict[str, Union[str, float]]
JsonPage = Optional[Dict[Literal["areas"], List[JsonPosition]]]


@dataclass
class Position:
    """Information for a position"""

    name: str
    x: float
    y: float
    width: float
    height: float

    @classmethod
    def from_json(cls, dict_values: JsonPosition):
        return cls(**dict_values)  # type: ignore  # dynamic typing


class Page(UserDict):
    """Information about positions on a page"""

    @classmethod
    def from_json(cls, page: JsonPage):
        """Get positions from JSON Dictionary"""
        if page is None:
            return cls()

        return cls({cast(str, p["name"]): Position.from_json(p) for p in page["areas"]})



JSON = Path("my_positions.json").read_text()
positions = json.loads(JSON)
page_1 = Page.from_json(positions["pages"][0])

我希望Mypy(或塔属或我使用的任何类型的Hinter)自动识别page_1 [“ my_name”]作为position

我可以改变什么?

I want to define a UserDict that reads values from JSON and stores a position for a given key. The JSON file looks like this:

{
    "pages": [
        {
            "areas": [
                {
                    "name": "My_Name",
                    "x": 179.95495495495493,
                    "y": 117.92792792792793,
                    "height": 15.315315315315303,
                    "width": 125.58558558558553
                },
                ...
              ]
        }
    ]
}

I would like to indicate to type linters (e.g. MyPy) that this dictionary as a key being a string and the values being a Position.

My current code is the following:

import json
from collections import UserDict
from dataclasses import dataclass, field
from pathlib import Path
from typing import Dict, List, Optional, Union

from typing_extensions import Literal


JsonPosition = Dict[str, Union[str, float]]
JsonPage = Optional[Dict[Literal["areas"], List[JsonPosition]]]


@dataclass
class Position:
    """Information for a position"""

    name: str
    x: float
    y: float
    width: float
    height: float

    @classmethod
    def from_json(cls, dict_values: JsonPosition):
        return cls(**dict_values)  # type: ignore  # dynamic typing


class Page(UserDict):
    """Information about positions on a page"""

    @classmethod
    def from_json(cls, page: JsonPage):
        """Get positions from JSON Dictionary"""
        if page is None:
            return cls()

        return cls({cast(str, p["name"]): Position.from_json(p) for p in page["areas"]})



JSON = Path("my_positions.json").read_text()
positions = json.loads(JSON)
page_1 = Page.from_json(positions["pages"][0])

I would like MyPy (or Pylance or whatever type hinter I use), to automatically recognize page_1["My_Name"] as being a Position.

What could I change?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

平定天下 2025-02-09 21:43:56

实际上,您可以将类型直接提供给userDict带有方括号([...])的

class Page(UserDict[str, Position]):
    ...

类型strong> python 3.6 或更早,这将行不通。

对于 python> = 3.7和< 3.9 ,您需要以下 to inscript collections.userdict并将其放在特定于键入检查的单独块中(使用常数type_checking):

from __future__ import annotations
from collections import UserDict
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    TypedUserDict = UserDict[str, Position]
else:
    TypedUserDict = UserDict


class Page(TypedUserDict):
    ...

for python 3.9+,无需其他进口或技巧。

Actually, you can directly provide the type to UserDict with square brackets ([...]) like you would with a Dict:

class Page(UserDict[str, Position]):
    ...

For Python 3.6 or earlier, this will not work.

For Python >=3.7 and <3.9, you need the following to subscript collections.UserDict and put it in a separate block specific to type checking (with constant TYPE_CHECKING):

from __future__ import annotations
from collections import UserDict
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    TypedUserDict = UserDict[str, Position]
else:
    TypedUserDict = UserDict


class Page(TypedUserDict):
    ...

For Python 3.9+, no additional import or trick is necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文