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

问题描述 投票:0回答:1

我想知道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 自动完成中受益,而不必在自己的代码中重写每个方法.)

有谁知道这是否可行?

python django pycharm python-typing
1个回答
1
投票

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

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

class Team(BaseTeam):
    ...

class Player(BasePlayer):

等等。

© www.soinside.com 2019 - 2024. All rights reserved.