正确的方法使用类型提示/泛型来描述类型类的参数("类型")

时间:2016-02-26 15:12:01

标签: python python-3.x generics typing

这似乎与Type Hinting: Argument Of Type Class类似,但是,那里接受的答案实际上并没有回答我的问题,所以也许问题表达不正确(?)

我有一个序列化/反序列化框架,可以从[IDE支持的]类型提示中受益匪浅。 API看起来像这样:

def serialize(obj:BaseModel) -> Dict[str,Any]:
    """ Serialize the object to a dictionary. """

def deserialize(data:Dict[str,Any], clazz:type) -> BaseModel:
    """ Deserialize dictionary into a model object of type clazz. """

序列化方法很好,但反序列化类型提示不是最佳的。我想指出deserialize的返回值将是clazz类型的对象(它是BaseModel的子类)。这个似乎就像仿制药可以帮助的东西一样,但我不确定如何表达我想要的东西。

T = TypeVar('T', bound=BaseModel)

def deserialize(data:Dict[str,Any], clazz:T) -> T:
    """ Deserialize dictionary into a model object of type clazz. """

这似乎是错误的,因为clazz是一个派生自T而不是类型为T的对象(实例)。

我已经完成了一些阅读但没有找到答案(谷歌这个特殊问题也很棘手)。有没有明显的东西我在这里丢失或者这只是python 3.5输入模块不支持?

当然,我仍然可以使用我的工具来推断类型,但希望如果有正确的方法来执行此操作,它将由类型检查实用程序实现。

2 个答案:

答案 0 :(得分:2)

由于一个类可以被认为是一个返回自身的实例,也许你可以尝试:

T = TypeVar('T', bound=BaseModel)

def deserialize(data: Dict[str, Any], clazz: Callable[..., T]) -> T:
    """ Deserialize dictionary into a model object of type clazz. """

省略号(...)表示未指定类的调用签名。所以是一个可调用的对象,它接受未指定的参数并返回T的实例。

答案 1 :(得分:0)

Python和类型检查器之间的脱节可能会有点棘手:

T = TypeVar('T', bound=BaseModel)

def deserialize(etc, T:type) -> T:

然后T既是您的参数名称,也是您的返回类型。我不知道你的IDE是否足够智能,或者愤怒到不满。 ; - )