有这样的需求,我有一个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_constructor
的typing hint
不是ConnConstructor
,而是type
,但只写type
太typing 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()