Jar*_*rad 10 python type-hinting python-3.5
使用Python/MyPy类型提示,可以使用.pyi存根将注释保存在单独的文件中以实现.我正在使用此功能来提供SQLAlchemy的ORM(更具体地说,flask_sqlalchemy插件)的基本提示.
模型定义如下:
class MyModel(db.Model):
id = db.Column()
...
...
Run Code Online (Sandbox Code Playgroud)
其中db.Model直接包含在SQLAlchemy中.例如,可以通过以下方式查询它们:
MyModel.query.filter({options: options}).one_or_none()
Run Code Online (Sandbox Code Playgroud)
其中filter()返回另一个Query,one_or_none()返回MyModel的实例(显然是None).
下面的.pyi文件成功提示上面的构造,虽然它不完整 - 没有办法提示返回类型one_or_none().
class _SQLAlchemy(sqlalchemy.orm.session.Session):
class Model:
query = ... # type: _Query
class _Query(sqlalchemy.orm.query.Query):
def filter(self, *args) -> query.Query: ...
def one_or_none(self) -> Any: ...
db = ... # type: _SQLAlchemy
Run Code Online (Sandbox Code Playgroud)
如何完全和一般地暗示上述内容,并提示one_or_none()的返回类型?我的第一次尝试是使用泛型,但看起来我无法访问所讨论的子类型(在给定的示例中,MyModel).为了说明一种非工作方法:
from typing import Generic, TypeVar
_T = TypeVar('_T')
class _SQLAlchemy(sqlalchemy.orm.session.Session):
class Model:
def __init__(self, *args, **kwargs):
self.query = ... # type: _Query[self.__class__]
class _Query(Generic[_T], sqlalchemy.orm.query.Query):
def filter(self, *args) -> _Query[_T]: ...
def one_or_none(self) -> _T: ...
db = ... # type: _SQLAlchemy
Run Code Online (Sandbox Code Playgroud)
有没有办法让这个工作?
对于具体和示例的道歉,但我试着用一个通用的例子简洁地写出这一点,它从来没有像现在那样清晰(可能仍然不多!)
另一个非工作方法(我知道这将限制必须调用myModelInstance.query ...而不是静态MyModel.query,但即使这不起作用):
from typing import Generic, TypeVar
_T = TypeVar('_T')
class _SQLAlchemy(sqlalchemy.orm.session.Session):
class Model:
@property
def query(self: _T) -> _Query[_T]: ...
class _Query(Generic[_T], sqlalchemy.orm.query.Query):
def filter(self, *args) -> _Query[_T]: ...
def one_or_none(self) -> _T: ...
db = ... # type: _SQLAlchemy
Run Code Online (Sandbox Code Playgroud)
幸运的是,类型注释存根现在可用于该特定问题https://github.com/dropbox/sqlalchemy-stubs
类型注释的确切实现Query可以在这里: https: //github.com/dropbox/sqlalchemy-stubs/blob/master/sqlalchemy-stubs/orm/query.pyi(存档)
| 归档时间: |
|
| 查看次数: |
516 次 |
| 最近记录: |