如何在Python中输入提示构建器模式?



希望在class AggregateMaker中为def make(self):添加类型提示,以便测试test_fruittest_tea中的代码将自动完成FruitTea方法/属性,而不是返回None

在Python 3.10中可能吗?

from dataclasses import dataclass
@dataclass
class Fruit:
name: str
smell: str
@dataclass
class Tea:
name: str
hot: bool
class AggregateMaker():
_fields: dict
@classmethod
def new(cls, **fields):
return cls(fields=None).with_(**fields)
###
#  How to type hint in here to return Fruit or Tea?
###
def make(self):
return self._make(self._fields)
def with_(self, **overrides):
copy = dict(self._fields)
for name, value in overrides.items():
copy[name] = value
return type(self)(copy)
class FruitMaker(AggregateMaker):
def __init__(self, fields):
if fields is None:
fields = {
"name": None,
"smell": None,
}
self._fields = fields
def _make(self, fields) -> Fruit:
return Fruit(**fields)
class TeaMaker(AggregateMaker):
def __init__(self, fields):
if fields is None:
fields = {
"name": None,
"hot": None,
}
self._fields = fields
def _make(self, fields) -> Tea:
return Tea(**fields)
def test_fruit():
durian = FruitMaker.new().with_(name="Durian").with_(smell="Strong").make()
assert durian.name == "Durian"
assert durian.smell == "Strong"
assert type(durian) is Fruit
def test_tea():
camomile = TeaMaker.new(name="Camomile", hot=True).make()
assert type(camomile) is Tea

我尽可能多地输入了我认为合理的内容,但仍然有空白。

我觉得用原型对象和对dataclasses.replace的调用来代替这些通常是有意义的。

(从其他地方的上下文中,我知道这在短期内是不实际的。)

from dataclasses import dataclass
from typing import Any, Generic, Type, TypeVar
T = TypeVar("T")
TMaker = TypeVar("TMaker", bound="AggregateMaker[Any]")
@dataclass
class Fruit:
name: str
smell: str
@dataclass
class Tea:
name: str
hot: bool
class AggregateMaker(Generic[T]):
_fields: dict[str, Any]

def __init__(self, fields: dict[str, Any] | None) -> None:
...
@classmethod
def new(cls: Type[TMaker], **fields: Any) -> TMaker:
return cls(fields=None).with_(**fields)
def make(self) -> T:
return self._make(self._fields)

def _make(self, fields: dict[str, Any]) -> T:
...
def with_(self: TMaker, **overrides: Any) -> TMaker:
copy = dict(self._fields)
for name, value in overrides.items():
copy[name] = value
return type(self)(copy)
class FruitMaker(AggregateMaker[Fruit]):
def __init__(self, fields: dict[str, Any]):
if fields is None:
fields = {
"name": None,
"smell": None,
}
self._fields = fields
def _make(self, fields: dict[str, Any]) -> Fruit:
return Fruit(**fields)
class TeaMaker(AggregateMaker[Tea]):
def __init__(self, fields: dict[str, Any]):
if fields is None:
fields = {
"name": None,
"hot": None,
}
self._fields = fields
def _make(self, fields: dict[str, Any]) -> Tea:
return Tea(**fields)
def test_fruit() -> None:
durian = FruitMaker.new().with_(name="Durian").with_(smell="Strong").make()
assert durian.name == "Durian"
assert durian.smell == "Strong"
assert type(durian) is Fruit
def test_tea() -> None:
camomile = TeaMaker.new(name="Camomile", hot=True).make()
assert type(camomile) is Tea

相关内容

  • 没有找到相关文章

最新更新