如何解决Mypy 在调用函数时出错,返回类型为 TypeVar 的 List of TypedDict
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.overload
与 typing.Literal
结合使用,以通知 MyPy 如果 get_items
使用 spider_name="espn-players"
调用,它将返回 list
的 {{ 1}} Player
,而如果使用 dicts
调用它,它将返回 spider_name="espn-matches"
list
的 Match
:
dicts
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。