Python: 什么时候应该使用子类而不是方法?

Python: when should you use subclasses instead of methods?

假设我正在尝试 class 两种搜索算法,二分搜索和线性搜索。在我看来,有三种方法可以做到这一点。

选项 1:使用 binary_searchlinear_search 两种方法制作 class Search()。搜索算法将取决于用户选择使用哪种方法。示例:用户将创建对象 s = Search(),然后使用 s.binary_search().

选项 2:使用方法 do_search 创建一个 class Search(),该方法基于什么调用两个私有方法 _binary_search_linear_search 值传递给 __init__ 参数。示例:用户将创建对象 b = Search('binary').

选项 3:使用两个子class Binary()Linear() 创建一个基础 class Search()。然后用户可以使用适当的 subclass 选择算法。示例:用户将创建对象 b = Binary().

我的问题是您应该使用三个选项中的哪一个,为什么?

我认为从设计的角度来看选项 3 是最好的,但我不太确定为什么。我也对其他观点感兴趣(不仅仅是设计)。

在这种特殊情况下,您可能根本不应该使用 classes,因为没有保存状态。请记住,classes 对于将数据与操作该数据的方法一起分组很有用。但是在二分查找中,没有数据。我的意思是,你得到一些输入(列表),然后你对该输入进行一些计算以产生一些输出(一个索引),然后你 return 输出,就是这样。搜索算法完成后没有什么可保存的。所以 class.

没有意义

但是假设您有一个场景,其中有一些原因需要保存状态。例如,假设您在同一个数组上进行多次搜索,您有理由相信连续搜索的结果通常会在数组中靠得很近。您可能希望保存每次搜索的结果,以便您可以通过搜索附近的索引来开始下一次搜索。在这种情况下,您会想要使用 class。在这种情况下,您可以根据存储的状态(在本例中为先前的结果)是否与您的所有算法相关来将选项 3 与其他选项区分开来。如果所有算法都可以使用相同的保存状态,那么拥有一个具有多种搜索方法的 class 可能是有意义的,并且默认情况下只选择最佳搜索方法,但允许客户端代码选择方法选择 - 这类似于选项 1 和选项 2 的组合。

def search(self, element, kind='binary'):
    if kind == 'binary':
        return self.binary_search(element)
    elif kind == 'linear':
        return self.linear_search(element)
    else:
        # error
def binary_search(self, element):
    ...
def linear_search(self, element):
    ...

但是如果不同的算法需要不同的保存状态,那么您可能需要使用子classes,或者通常,不同的classes 用于不同的算法。

我认为使用通用的 search() 方法比使用针对个别算法的特定搜索方法(例如 binary_search()linear_search()) 因为在很多情况下,你知道哪种算法最好并且可以选择那个。我能想到的不提供这种意义上的通用方法的唯一原因是,如果您真的不知道要使用哪种算法,如果在不同情况下需要不同的算法,并且您需要让客户端代码选择使用哪个算法。