微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Mypy 在调用函数时出错,返回类型为 TypeVar 的 List of TypedDict

如何解决Mypy 在调用函数时出错,返回类型为 TypeVar 的 List of TypedDict

我试图在类中键入提示函数,但在 mypy 中出现以下错误

get_items 函数调用后台运行的scrapyRT API 并根据蜘蛛名和url 输出 蜘蛛espn-matches以List[Match]的形式返回输出espn-players以List[Player]的形式返回输出

get_items 函数返回 Player dict 列表或 Matches dict 列表

app/fantasy_cricket/ScrapyRTClient.py:74: error: Incompatible return value type (got "List[Player]",expected "List[Match]")
Found 1 error in 1 file (checked 1 source file)

这是我的代码

import requests
import sys
if sys.version_info >= (3,8):
    from typing import TypedDict
else:
    from typing_extensions import TypedDict
from typing import TypeVar,List,Union,Optional

class Player(TypedDict):
    name: str
    role: str
    image: str
    player_id: str

class Match(TypedDict):
    runs: Optional[int]
    boundaries: Optional[int] 
    sixes: Optional[int]
    wicket : Optional[int]
    Maiden: Optional[int]
    Catch: Optional[int]
    Stump: Optional[int]
    match_id: str

Item = TypeVar("Item",Player,Match)

class espn_scrapyrt_client:
    def __init__(self) -> None:

        self.url = "http://localhost:9080/crawl.json"

    def get_items(self,spider_name: str,url: str) -> List[Item]:

        items = requests.get(self.url,params={"spider_name": spider_name,"url": url})

        return items.json()["items"]

    def get_player_dets(self,team: str,players: List[str]) -> List[Player]:

        team_map = {
            "India": "https://www.espncricinfo.com/ci/content/player/index.html?country=6","Australia": "https://www.espncricinfo.com/ci/content/player/index.html?country=2","England": "https://www.espncricinfo.com/ci/content/player/index.html?country=1","Bangladesh": "https://www.espncricinfo.com/ci/content/player/index.html?country=25","New Zealand": "https://www.espncricinfo.com/ci/content/player/index.html?country=5","South Africa": "https://www.espncricinfo.com/ci/content/player/index.html?country=3","Pakistan": "https://www.espncricinfo.com/ci/content/player/index.html?country=7","Sri Lanka": "https://www.espncricinfo.com/ci/content/player/index.html?country=8","West Indies": "https://www.espncricinfo.com/ci/content/player/index.html?country=4","Afghanistan": "https://www.espncricinfo.com/ci/content/player/index.html?country=40",}

        team_players = self.get_items(spider_name="espn-players",url=team_map[team])
        names = {player["name"]: i for i,player in enumerate(team_players)}
        player_det = []
        for player in players:
            player_name = player.strip().split()
            if len(player_name) == 1:
                p = [names[name] for name in names if player.strip() in name]
            elif len(player_name) > 1:
                p = [
                    names[name]
                    for name in names
                    if player_name[0] in name and player_name[-1] in name
                ]
            if p!=[]:
                player_det.append(team_players[p[0]])
        return player_det

    def get_match_de(self,player_id: str) -> List[Match]:

        x = self.get_items(spider_name="espn-matches",url = "https://stats.espncricinfo.com/ci/engine/player/253802.html?class=1&orderby=start&orderbyad=reverse&template=results&type=allround&view=match")
        print(x)
        return x //error here

任何帮助将不胜感激! 谢谢!!

解决方法

这里的问题在于您的 get_items 方法中的这两行:

items = requests.get(self.url,params={"spider_name": spider_name,"url": url})
return items.json()["items"]

MyPy 不知道调用 dict 产生的 items.json() 中键和值的类型是什么。 MyPy 在这里的混乱会渗透到您的其余代码中,并最终在第 74 行中产生错误。

我们可以通过使用 typing.cast 为 MyPy 提供有关此字典中键和值类型的一些信息来解决此问题。我们还可以使用 typing.overloadtyping.Literal 结合使用,以通知 MyPy 如果 get_items 使用 spider_name="espn-players" 调用,它将返回 list 的 {{ 1}} Player,而如果使用 dicts 调用它,它将返回 spider_name="espn-matches" listMatch

dicts

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。