我是 python 新手(3.6.2 是我正在使用的版本)。
我目前正在将 DSL 实现从 Scala 移植(尝试移植)到 python,用于某些强制使用 python 的项目。
因此,我正在寻找一种方法来有效地编写不可变的类层次结构以支持使用 mypy 进行类型检查的方式来表示 ADT。
我第一次遇到macropy,它在python中复制scala案例类和模式匹配,但只兼容python 2.7.x(无论如何都不能与mypy一起使用)。
我做了一些更多的研究,然后输入了.NamedTuple 和 abc.ABC。所以现在我正试图找到一种方法来结合 typing.NamedTuple 和 abc.ABC 的好处,以便能够将 mixins 添加到 namedtuples。
我希望能够编写这种代码:
from typing import *
from abc import ABC, abstractmethod
class M(ABC):
@abstractmethod
def m1(self, it: Iterable[str]) -> str:
pass
class NT(NamedTuple):
attr1: str
attr2: Union[bool, float]
class C1(NT,M):
def m(self, it: Iterable[str]) -> str:
return attr1.join(it)
class C2(NT,M):
pass
c1 = C1('foo',12)
c1.m([str(i) for in in range(10)]) # would work
c2 = C2('bar',12.0)
c2.m([str(i) for in in range(10)]) # would fail because abstractmethod not implemented
上面的代码使用 mypy 运行类型检查,但在 C2.m 调用中失败(方法调用只返回 None)。
所以我进一步搜索并找到了这个 collections.namedtuple + Mix-In 的配方:abc.namedtuple
我试图将配方从 collections.namedtuple 调整为 typing.NamedTuple,但无法理解配方中涉及的相当复杂和脆弱的 python 机器。有什么明显的方法可以使这项工作吗?