Python如何向类添加Typing提示?



有这样的需求,我有一个create_connection函数,conn_constructor可以是SqlLiteConnection, PGsqlConnection, MysqlConnection等中的任何一个。

我可以给conn_constructor参数添加什么类型提示来实现,参数是什么类,返回值是什么类的实例?

显然,Any不是一件好事,因为IDE的代码完成丢失了

from typing import TypeVar, Generic
from abc import abstractclassmethod
from typing import Any

class BaseConnection:
@abstractmethod
def connect(self):
pass

class MysqlConnection(BaseConnection):
def connect(self):
pass

class PGsqlConnection(BaseConnection):
def connect(self):
pass

class SqlLiteConnection(BaseConnection):
def connect(self):
pass

def create_connnection(conn_constructor: Any) -> Any:
return conn_constructor()

if __name__ == '__main__':
connection = create_connnection(conn=SqlLiteConnection)

您可以使用TypeVar

from abc import abstractmethod
from typing import Type, TypeVar

class BaseConnection:
@abstractmethod
def connect(self):
pass

class MysqlConnection(BaseConnection):
def connect(self):
pass

class PGsqlConnection(BaseConnection):
def connect(self):
pass

class SqlLiteConnection(BaseConnection):
def connect(self):
pass

ConnT = TypeVar("ConnT", bound=BaseConnection)

def create_connnection(conn_constructor: Type[ConnT]) -> ConnT:
return conn_constructor()

if __name__ == '__main__':
connection = create_connnection(SqlLiteConnection)

看到它工作https://mypy-play.net/?mypy=latest&python=3.10&gist=1afc3a41adf2ca4be75d6273b9d26c0d

使用conn_constructor: Type[ConnConstructor]

conn_constructortyping hint不是ConnConstructor,而是type,但只写typetyping less了,所以我们可以用方括号Type[ConnConstructor]

这样,就不会有IDE独自自动完成了!

from typing import TypeVar, Generic
from abc import abstractclassmethod
from typing import Type
ConnConstructor = TypeVar('ConnConstructor')

class BaseConnection:
@abstractmethod
def connect(self):
pass

class MysqlConnection(BaseConnection):
def connect(self):
pass

class PGsqlConnection(BaseConnection):
def connect(self):
pass

class SqlLiteConnection(BaseConnection):
def connect(self):
pass

def create_connnection(conn_constructor: Type[ConnConstructor]) -> ConnConstructor:
return conn_constructor()

if __name__ == '__main__':
connection = create_connnection(conn_constructor=SqlLiteConnection)
connection.connect()

最新更新