检查函数是否在Python中调用之前引发NotImplementedError

Check if a function raises NotImplementedError before calling it in Python

我有以下简化方案:

1
2
3
4
5
6
7
8
9
10
11
12
class NetworkAnalyzer(object):
    def __init__(self):
       print('is _score_funct implemented?')

    @staticmethod
    def _score_funct(network):
        raise NotImplementedError

class LS(NetworkAnalyzer):
    @staticmethod
    def _score_funct(network):
        return network

我正在寻找我应该使用什么来代替print('is _score_funct implemented?'),以确定子类是否已经实现了_score_funct(network)

注意:如果有一种更为Python式的/传统的代码结构方式,我也会感谢它的提及。我这样定义它的原因是,一些NetworkAnalyzer子类在其定义中具有"得分"功能,而那些没有"得分"功能的子类将具有不同的变量初始化,尽管它们具有相同的结构


使用抽象基类,除非该类实现所有抽象方法,否则将无法实例化该类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import abc

class NetworkAnalyzerInterface(abc.ABC):
    @staticmethod
    @abc.abstractmethod
    def _score_funct(network):
        pass

class NetworkAnalyzer(NetworkAnalyzerInterface):
    def __init__(self):
        pass

class LS(NetworkAnalyzer):
    @staticmethod
    def _score_funct(network):
        return network

class Bad(NetworkAnalyzer):
    pass

ls = LS()   # Ok
b = Bad()   # raises TypeError: Can't instantiate abstract class Bad with abstract methods _score_funct


我不是元类/类专家,但这里有一个方法可以在简单的情况下工作(不确定它是否像复杂/嵌套类命名空间中那样工作):

要检查方法是否被重写,可以在函数名上尝试一个getattr,然后检查限定名(使用字符串分区类部分就足够了):

1
2
3
4
5
class NetworkAnalyzer(object):
    def __init__(self):
        funcname ="_score_funct"
        d = getattr(self,funcname)
        print(d.__qualname__.partition(".")[0] == self.__class__.__name__)

如果_score_functLS中定义,那么d.__qualname__LS._score_funct,否则是NetworkAnalyzer._score_funct

如果该方法是在LS类级别实现的,那么它就可以工作。否则,您可以替换为:

1
d.__qualname__.partition(".")[0] !="NetworkAnalyzer"

当然,如果该方法被某些代码重写,而这些代码引发了NotImplementedError,那么这将不起作用…此方法不检查方法代码(无论如何都是有害的)