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

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

有谁知道这是否可能?

最佳答案

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

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

class Team(BaseTeam):
    ...

class Player(BasePlayer):
等等。

关于python - Python 3.5 类型提示是否允许协变返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38698765/

相关文章:

python-3.x - 正确的方法来删除然后重新索引ES文档

Python 检查将方法识别为 FunctionType 而不是 types.MethodType

python - DRF 社会 OAUTH 2 详细信息

python-3.x - 如何使用所有列创建频率矩阵

python - 无法在 App Engine 上捕获 MySQLdb.OperationalError

python - 使用 openweathermAP 将 json 加载到 Pandas 数据帧

python - 如何根据与其他匹配项的接近程度来过滤外围匹配项?

python - 连接 django 到 mysql 时出错

python - Django REST 框架 : AttributeError: Serializer object has no attribute 'Meta'

python - Django:如何测试 'HttpResponsePermanentRedirect'