Python 3.5类型提示是否允许协变返回类型?

时间:2016-08-01 12:22:03

标签: python django python-3.x pycharm type-hinting

我想知道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的属性。这似乎与return type covariance密切相关。

我有一种感觉,我需要像这样使用GenericTypeVar

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自动完成中受益,而不需要在自己的代码中覆盖每个方法。)

有人知道这是否可行?

1 个答案:

答案 0 :(得分:0)

那是因为在使用基类的继承时,您不会重新定义基类的方法,因此 Pycharm(以及任何智能感知自动完成)将假设函数的返回保持不变。如果您希望更改自动完成或建议,则可以重新定义方法,并且只更改返回类型。例如:

class League(BaseLeague):
    def get_teams(self) -> List[Team]:
        return super().get_teams()
    ...

class Team(BaseTeam):
    ...

class Player(BasePlayer):

等等。