我想知道Python 3.5类型提示(
typing
模块)是否支持返回类型协变,主要用于PyCharm的自动补全。
这是我的运动框架的基础课程:
class BaseLeague:
def get_teams(self) -> List[BaseTeam]:
...
...
class BaseTeam:
def get_captain(self) -> BasePlayer:
...
def get_players(self) -> List[BasePlayer]:
...
...
class BasePlayer:
team = None # type: BaseTeam
...
(我还遗漏了很多方法,比如 BaseLeague 上返回 BaseTeam/BasePlayer/BaseLeague 对象的方法等)
我有多个模块并行对这 3 个类进行子类化,并添加/覆盖方法和属性。
在
hockey/models.py
,我有:
class League(BaseLeague):
...
class Team(BaseTeam):
...
class Player(BasePlayer):
...
在
football/models.py
中,我也有同样的事情:
class League(BaseLeague):
....
class Team(BaseTeam):
...
class Player(BasePlayer):
...
(我有20多种其他运动,如足球、棒球等..)
在 PyCharm 中,当我处于
football.models.Team
并输入 self.get_captain().
时,PyCharm 会向我显示基类 BasePlayer
的属性,但我希望它向我显示子类 football.models.Player
的属性。这似乎与返回类型协方差密切相关。
我有一种感觉,我需要像这样使用
Generic
和 TypeVar
:
Player = TypeVar('Player', covariant=True)
Team = TypeVar('Team', covariant=True)
League = TypeVar('League', covariant=True)
class BaseTeam(Generic[Player, Team, League]):
def get_players(self) -> List[Player]:
...
然后在
football.models
我会做类似的事情:
class Team(BaseTeam[Player, Team, League]):
...其中 Player、Team、League 是对同一模块中子类的引用。
但是它不起作用(PyCharm 根本没有显示任何自动完成功能),并且我不确定我是否使用了正确的语法。
我想让这个工作正常进行,因为我的基类是我框架 API 的一部分,并且我的用户对它们进行了数百次子类化,所以我希望他们能够从 PyCharm 自动完成中受益,而不必在自己的代码中重写每个方法.)
有谁知道这是否可行?
这是因为当使用基类的继承时,您不会重新定义基类的方法,因此 Pycharm(以及任何智能感知自动完成功能)将假设函数的返回保持不变。如果您希望更改自动完成或建议,则可以重新定义方法,并且仅更改返回类型。例如:
class League(BaseLeague):
def get_teams(self) -> List[Team]:
return super().get_teams()
...
class Team(BaseTeam):
...
class Player(BasePlayer):
等等。