繁体   English   中英

Python:如何在 mixin 方法中指定 function 返回类型

[英]Python: How to specify function return type in a mixin method

我正在尝试准确注释 mixin 方法的返回类型。

下面的最小示例:

from dataclasses import dataclass, field
from typing import Dict, Protocol

class HasStore(Protocol):
    store: dict


class StoreGetMixin:
    def __getitem__(self: HasStore, key: str):  # what to put in -> type?
        return self.store[key]


@dataclass
class ThingOne:
    size: int


@dataclass
class ThingTwo:
    name: str


@dataclass
class Ones(StoreGetMixin):
    store: Dict[str, ThingOne] = field(default_factory=dict)


@dataclass
class Twos(StoreGetMixin):
    store: Dict[str, ThingTwo] = field(default_factory=dict)


ones = Ones()
ones.store = {"a": ThingOne(1), "b": ThingOne(2)}
one = ones["a"]  # <- this should be typed as a ThingOne

twos = Twos()
twos.store = {"a": ThingTwo("one"), "b": ThingTwo("two")}
two = twos["a"]  # <- this should be typed as a ThingTwo

所以我正在尝试编写一个可重用的mixin,它可以访问各种数据类中的store字典。 但我不知道如何告诉__getitem__方法它返回什么类型。

我见过输入self的例子,但在这种情况下我需要输入self.store mypy 可以将self.store的类型视为dict (我假设这来自HasStore ),但它不知道键或值类型。

这可能吗?

我需要更好地注释HasStore协议的store吗? 我试过了,例如dict[str, T]但我不能让它工作,因为如果这样使用T就不会被实例化。

我这样做的原因是使用 Mashumaro 将我的数据类序列化为 JSON 并且我无法弄清楚如何存储一个以str为键的普通字典而不在名为store的数据类中创建单个属性。 所以其中有一些,它们都有一个名为storedict ,所以我想我会使用collections.abc.MutableMapping来允许我通过下标访问store ,例如twos["a"] 因此,我编写了 mixin 来做到这一点,但如果我不需要,很遗憾失去所有类型。

非常感谢任何指针:)

通用协议应该可以工作(此处的文档: https://mypy.readthedocs.io/en/stable/generics.html#generic-protocols ):

T = TypeVar('T')


class HasStore(Protocol[T]):
    store: Dict[str, T]


class StoreGetMixin(HasStore[T]):

    def __getitem__(self, key: str) -> T:  # what to put in -> type?
        return self.store[key]


@dataclass
class ThingOne:
    size: int


@dataclass
class ThingTwo:
    name: str


@dataclass
class Ones(StoreGetMixin[ThingOne]):
    store: Dict[str, ThingOne] = field(default_factory=dict)


@dataclass
class Twos(StoreGetMixin[ThingTwo]):
    store: Dict[str, ThingTwo] = field(default_factory=dict)


ones = Ones()
ones.store = {"a": ThingOne(1), "b": ThingOne(2)}
one = ones["a"]  # <- this should be typed as a ThingOne
reveal_type(one)
twos = Twos()
twos.store = {"a": ThingTwo("one"), "b": ThingTwo("two")}
two = twos["a"]  # <- this should be typed as a ThingTwo
reveal_type(two)

output 是:

note: Revealed type is 'experiment.ThingOne*'
note: Revealed type is 'experiment.ThingTwo*'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM