python - 类属性的类型提示
问题描述
我有一个包含许多模型和许多基于类的视图的 Web 应用程序。大部分代码看起来像这样
from typing import TypeVar, Type
M = TypeVar('M', bound='Model')
TypeModel = Type[M]
# ---------- models
class Model:
@classmethod
def factory(cls: TypeModel) -> M:
return cls()
class ModelOne(Model):
def one(self):
return
class ModelTwo(Model):
def two(self):
return
# ---------- views
class BaseView:
model: TypeModel
@property
def obj(self) -> M:
return self.model.factory()
def logic(self):
raise NotImplementedError
class One(BaseView):
model = ModelOne
def logic(self):
self.obj. # how can i get suggest of methods of ModelOne here?
...
class Two(BaseView):
model = ModelTwo
def logic(self):
self.obj. # how can i get suggest of methods of ModelTwo here?
...
我想要一个属性obj
,它是视图中指定模型的实例。我怎样才能做到这一点?谢谢
解决方案
您需要使您的BaseView
类相对于M
. 所以,你应该这样做:
from typing import TypeVar, Type, Generic
M = TypeVar('M', bound='Model')
# Models
class Model:
@classmethod
def factory(cls: Type[M]) -> M:
return cls()
class ModelOne(Model):
def one(self):
return
class ModelTwo(Model):
def two(self):
return
# Views
# A BaseView is now a generic type and will use M as a placeholder.
class BaseView(Generic[M]):
model: Type[M]
@property
def obj(self) -> M:
return self.model.factory()
def logic(self):
raise NotImplementedError
# The subclasses now specify what kind of model the BaseView should be
# working against when they subclass it.
class One(BaseView[ModelOne]):
model = ModelOne
def logic(self):
self.obj.one()
class Two(BaseView[ModelTwo]):
model = ModelTwo
def logic(self):
self.obj.two()
一注:我摆脱了你的TypeModel
类型别名。这部分是风格上的,部分是务实的。
从风格上讲,当我查看类型签名时,我希望能够立即确定它是否使用泛型/类型变量。使用类型别名往往会掩盖这一点/我真的不喜欢使用上下文相关类型。
务实地说,当您过度使用包含类型变量的类型别名时,PyCharm 的类型检查器和 mypy 都会有点困难。
推荐阅读
- php - 传递给 App\Http\Controllers\FrontEnd\paymentController::submit_payment_wallet() 的参数 1 必须是 App\Models\User 的实例,给定 null,
- android - 为什么我的模拟器没有在 Android Studio 中启动
- google-sheets - 如何使用 arrayformula 以便获得上次使用的单元格值?
- c# - 如何将回调函数嵌入触发它的函数中?
- python - 我怎样才能更好地优化这个 pygame 项目?太慢了
- python - 格式化 JSON 有效负载以传递给 python 中的 API POST 调用
- docker - zfs:文件系统有依赖的克隆
- firebase - 将文档列为标题,将集合列为 Flutter 屏幕的 Firebase 的副标题
- java - tomcat HTTP 状态 404 – GCP VM 升级后未找到
- javascript - 字段名称包含空格时的猫鼬排序?