类属性的类型提示

时间:2018-09-15 14:11:41

标签: python inheritance type-hinting

我有一个Web应用程序,其中包含许多模型和许多基于类的视图。大多数代码看起来像这样

<end>

我想要一个属性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? ... ,它是视图中指定模型的实例。我该如何实现? 谢谢

1 个答案:

答案 0 :(得分:3)

您需要使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类型别名。这部分是风格上的,部分是实用的。

通常,当我查看类型签名时,我希望能够立即确定它是否在使用泛型/ typevar。使用类型别名往往会使/我不太喜欢使用上下文相关的类型。

实用上,当您过多使用包含typevars的类型别名时,PyCharm的类型检查器和mypy都趋于有些挣扎。