禁止向Python子类添加新方法

禁止向Python子类添加新方法,python,python-3.x,class,inheritance,abstract-class,Python,Python 3.x,Class,Inheritance,Abstract Class,我有两个类,它们应该为两个独立的库(让我们称它们为LibA和LibB)实现相同的测试用例。到目前为止,我定义了要在抽象基类中实现的测试方法,该基类确保两个测试类都实现了所有期望的测试: 从abc导入abc,abstractmethod 类别测试(ABC): @抽象方法 def测试_-foo(自身): 通过 类TestsA(MyTests): def测试_-foo(自身): 通过 类TestsB(MyTests): def测试_-foo(自身): 通过 这正如预期的那样工作,但仍然可能发生的情况

我有两个类,它们应该为两个独立的库(让我们称它们为LibA和LibB)实现相同的测试用例。到目前为止,我定义了要在抽象基类中实现的测试方法,该基类确保两个测试类都实现了所有期望的测试:

从abc导入abc,abstractmethod
类别测试(ABC):
@抽象方法
def测试_-foo(自身):
通过
类TestsA(MyTests):
def测试_-foo(自身):
通过
类TestsB(MyTests):
def测试_-foo(自身):
通过
这正如预期的那样工作,但仍然可能发生的情况是,在LibB上工作的人意外地将
test\u bar()
方法添加到
TestB
而不是基类。在这种情况下,
TestA
类中缺少的
test\u bar()


有没有办法禁止向(抽象)基类添加新方法?目标是强制在基类中添加新方法,从而强制在所有派生类中实现新方法。

是。它可以通过元类完成,也可以从Python3.6开始,在基类的
\uuuu init\u子类\uuuu
中进行检查

\uuuu init\u sublass\uuuu
是语言在每次实例化子类时调用的一种特殊方法。因此,它可以检查新类是否有任何超类中不存在的方法,并在声明子类时引发TypeError。(
\uuuu init\u子类
自动转换为classmethod)

基本类(ABC):
...
定义初始子类(cls,*args,**kw):
超级()
#通过检查'cls.\uuuu dict.\uuuuu',我们选择直接在类上声明的所有方法
对于名称,属性在cls.\u dict\u.items()中:
attr=getattr(cls,name)
如果不可调用(属性):
持续
对于cls中的超类。\uuuMRO\uuuu[1:]:
如果目录中的名称(超类):
打破
其他:
#在超类中找不到方法:
raise TypeError(f“在{cls.\u_name\u_}中定义的方法{name}在超类中不存在”)

请注意,与未实现的抽象方法引发的TypeError不同,此错误是在类声明时而不是在类实例化时引发的。如果需要后者,则必须使用元类并将检查移动到其
\uuuu call\uuuu
方法-但是这会使事情变得复杂,就像一个方法是在一个从未实例化的中间类中创建的,当该方法在叶子类中可用时,它不会出现。我想您需要的是更多关于上述代码的内容。

hasattr(cls,name)
是否可以替代
for
循环?这里有两个for循环。如果您总是有一个基类和imediate子类,那么,yes-`hasattr(name,cls.\uu mro\uuu[1])将代替第二个for循环。外部for循环显然必须在那里检查所有属性。