gpt4 book ai didi

python - 将单独的分支组合成通用结构的设计模式

转载 作者:行者123 更新时间:2023-12-04 07:15:07 25 4
gpt4 key购买 nike

我有由数据加载器和数据转换器组成的应用程序。每个加载器和每个转换器都是抽象基础加载器和抽象基础转换器的子类,我将在下面的示例中省略它们。具体加载器和转换器之间存在 1:1 映射,即已知哪个加载器和转换器属于一起。
假设我们有两个加载器和两个转换器,处理数据

class Data1: ...

class Data2: ...


class Loader1:
def get_data(self) -> Data1: ...

class Loader2:
def get_data(self) -> Data2: ...


class Transformer1:
def transform_data(self, data: Data1) -> None: ...

class Transformer2:
def transform_data(self, data: Data2) -> None: ...

这些类现在可以组合到应用程序中
class App1:
Loader = Loader1
Transformer = Transformer1

class App2:
Loader = Loader2
Transformer = Transformer2

附带工厂
from typing import Union, Type

def make_app(use_app1: bool) -> Union[Type[App1], Type[App2]]:
if use_app1:
return App1
else:
return App2
这就是我想使用上面的方式
def main(use_app1: bool) -> None:
app = make_app(use_app1)
loader = app.Loader()
data = loader.get_data()
transformer = app.Transformer()
transformer.transform_data(data=data)

但是, mypy complains :
error: Argument "data" to "transform_data" of "Transformer1" has incompatible type "Union[Data1, Data2]"; expected "Data1"  [arg-type]
error: Argument "data" to "transform_data" of "Transformer2" has incompatible type "Union[Data1, Data2]"; expected "Data2" [arg-type]
有没有办法说服 mypy那个 Twig Loader1 -> Data1 -> Transformer1Loader2 -> Data2 -> Transformer2是分开的,不会混在一起?
是否有可用于此用例的替代模式?

最佳答案

好的,这是解决此问题的第三次尝试。在这次尝试中,我使用抽象协议(protocol)来告诉 MyPy,事实上,在很多这样的函数中,返回的具体类型并不重要,只要返回的对象具有特定的接口(interface)即可。

from typing import Type, Protocol, cast


### ABSTRACT INTERFACES ###


class DataProto(Protocol): ...


class LoaderProto(Protocol):
def get_data(self) -> DataProto: ...


class TransformerProto(Protocol):
def transform_data(self, data: DataProto) -> None: ...


class AppProto(Protocol):
Loader: Type[LoaderProto]
Transformer: Type[TransformerProto]


### CONCRETE IMPLEMENTATIONS ###


class Data1: ...


class Data2: ...


class Loader1:
def get_data(self) -> Data1: ...


class Loader2:
def get_data(self) -> Data2: ...


class Transformer1:
def transform_data(self, data: Data1) -> None: ...


class Transformer2:
def transform_data(self, data: Data2) -> None: ...


class App1:
Loader = Loader1
Transformer = Transformer1


class App2:
Loader = Loader2
Transformer = Transformer2


GenericAppClassType = Type[AppProto]


def make_app(use_app1: bool) -> GenericAppClassType:
if use_app1:
return cast(GenericAppClassType, App1)
else:
return cast(GenericAppClassType, App2)


def main(use_app1: bool) -> None:
app = make_app(use_app1)
loader = app.Loader()
data = loader.get_data()
transformer = app.Transformer()
transformer.transform_data(data=data)
在 mypy 操场上试一试 here .

关于python - 将单独的分支组合成通用结构的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68812899/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com