这是一个由两部分组成的问题,但第二部分取决于第一部分。
出于教育目的,我正在尝试为组(抽象代数的概念)实现一个抽象基类和测试套件。代数群的部分定义等同于类型约束,我想在 ABC 上实现该类型约束,如果具体类上的方法不符合该约束,我会抱怨。
对于逻辑下的布尔值组,我有一个第一遍实现and
,但它至少有两个问题,我希望你能帮我解决它。
from __future__ import annotations
from abc import ABC, abstractmethod
class AbsGroup(ABC):
@abstractmethod
def op(self, other: AbsGroup) -> AbsGroup: # <-- Line-of-interest #1
pass
class Bool(AbsGroup):
def __init__(self, val="False"):
if val not in ["True", "False"]:
raise ValueError("Invalid Bool value %s" % val)
self.val = val
def op(self, other):
"""Logical AND"""
if self.val == "True" and other.val == "True": # <-- Line-of-interest #2
return Bool("True")
return Bool("False")
def __eq__(self, other):
return self.val == other.val
def __repr__(self):
return self.val
首先:兴趣线#1 是在做类型约束工作,但当前的实现是错误的。它只检查该方法是否接收并返回一个AbsGroup
实例。这可以是任何AbsGroup
实例。我希望它检查它所继承的具体类,它接收并返回该具体类的实例(因此在Bool
它接收并返回的实例的情况下Bool
)。练习的重点是在一个位置执行此操作,而不必在每个具体类上专门设置它。我认为这是通过一些类型提示泛型完成的,这些泛型比我尚未深入研究的类型提示要深一些。我该怎么做呢?
其次:如何检查具体方法是否符合抽象类型提示?我的 IDE (PyCharm) 中的类型检查器在 Line-of-interest #2 处抱怨,因为它预计other
是 type AbsGroup
,它没有val
属性。这是意料之中的,如果我能找出第一个问题的解决方案,它就会消失,但我的 IDE 是我能找到的唯一能注意到这种差异的东西。mypy
默认情况下对此事保持沉默,flake8 和 pylint 也是如此。PyCharm 很好,但如果我想将其合并到工作流中,如果我的具体方法不符合抽象签名,我必须运行什么命令会失败?