pycharm Python中的区分联合

xzv2uavs  于 2023-01-30  发布在  PyCharm
关注(0)|答案(1)|浏览(122)

bounty将在6天后过期。回答此问题可获得+400声望奖励。mnowotka希望引起更多人对此问题的关注:我希望赢家能提供一个符合问题约束的解决方案,特别是“你为什么要完全不同地做这件事”的答案,除非他们清楚地提出一个替代方法,并附有代码示例和利弊讨论,否则将不予接受。

假设我有一个基类和两个派生类。我还有一个工厂方法,它返回其中一个类的对象。问题是,mypy或IntelliJ无法确定对象是哪种类型。他们知道对象可以是两种类型,但不知 prop 体是哪种类型。有没有什么方法可以帮助mypy/IntelliJ确定这一点,而不必在conn变量名旁边放置类型提示?

import abc
import enum
import typing

class BaseConnection(abc.ABC):
    @abc.abstractmethod
    def sql(self, query: str) -> typing.List[typing.Any]:
        ...

class PostgresConnection(BaseConnection):

    def sql(self, query: str) -> typing.List[typing.Any]:
        return "This is a postgres result".split()

    def only_postgres_things(self):
        pass

class MySQLConnection(BaseConnection):

    def sql(self, query: str) -> typing.List[typing.Any]:
        return "This is a mysql result".split()

    def only_mysql_things(self):
        pass

class ConnectionType(enum.Enum):
    POSTGRES = 1
    MYSQL = 2

def connect(conn_type: ConnectionType) -> typing.Union[PostgresConnection, MySQLConnection]:
    if conn_type is ConnectionType.POSTGRES:
        return PostgresConnection()
    if conn_type is ConnectionType.MYSQL:
        return MySQLConnection()

conn = connect(ConnectionType.POSTGRES)
conn.only_postgres_things()

看看IntelliJ是如何处理的:

正如您所看到的两种方法:当我希望IntelliJ/mypy从我传递给connect函数的类型中找出它时,建议使用only_postgres_thingsonly_mysql_things

ljo96ir5

ljo96ir51#

您可以尝试将typing.overloadtyping.Literal组合使用,如下所示:

@typing.overload
def connect(type_: typing.Literal[ConnectionType.POSTGRES]) -> PostgresConnection:
    ...

@typing.overload
def connect(type_: typing.Literal[ConnectionType.MYSQL]) -> MySQLConnection:
    ...

def connect(type_):
    if type_ is ConnectionType.POSTGRES:
        return PostgresConnection()
    if type_ is ConnectionType.MYSQL:
        return MySQLConnection()

我用type_替换了type,这样就不会隐藏内置函数,而且使用is而不是==比较枚举值是惯用的。

相关问题