Skip to main content
 首页 » 编程设计

python之强制继承类型的兼容性 (Python)

2025年05月04日12xxx_UU

假设有人给了你一对现有的协同工作的类:

class non_unique_collection: 
    def __init__(self): 
        self.all_items = [] 
    def add_new_item(self, item): 
        self.all_items.append(item) 
    def __len__(self): 
        return len(self.all_items) 
    ## ... 
    ## there are several other useful functions here 
    ## ... 
    def overlap(self, n_u_tuple): 
        # do some things here 
        pass 
 
class non_unique_ranked_collection: 
    def __init__(self, some_scores_and_items): 
        self.ranked_items = sorted(some_scores_and_items) 

我想使用该类的许多函数(例如 __len__),但我想更改一些非常基本的东西:

class unique_collection(non_unique_collection): 
    def __init__(self): 
        self.all_items = set([]) 
    def add_new_item(self, item): 
        self.all_items.add(item) 

我还想将派生的 unique_collection 类与另一个新类 unique_ranked_collection 一起使用:

class unique_ranked_collection(non_unique_ranked_collection): 
    def __init__(self, some_scores_and_items): 
        # average scores for duplicate items 
        items_to_scores = {} 
        for score, item in some_scores_and_items: 
            if item in items_to_scores: 
                items_to_scores[item].append(score) 
            else: 
                items_to_scores[item] = [ score ] 
        average_scores_and_unique_items = dict( [ (sum(items_to_scores[item])/float(len(items_to_scores[item])), item) for item in items_to_scores ] ) 
        self.ranked_items = sorted(average_scores_and_unique_items) 

这是我的问题:

什么是最好的方法来使 overlap 函数可以与 non_unique_collection 和 non_unique_ranked_collection< 一起使用 或使用 unique_collection 和 unique_ranked_collection(但 不 unique... 和 >non_unique... 类型)?我开始使用 isinstance 放入一些断言语句,但它开始看起来很乱,我想寻求建议。

我能想到的最好的事情是拥有两个基类,unique... 和 non_unique... 类型都从中继承。你怎么看?

非常感谢。

PS-- 我知道编写代码所针对的这个特定问题非常无趣,但这只是一个示例。

请您参考如下方法:

如果你真的想强制执行此操作,请三思。不建议对 Python 进行严格的类型检查,因为它会阻止“鸭子打字”。

此外,面向对象编程中的继承模型是是一种关系。由于 unique_ranked_collection 继承自 non_unique_ranked_collection,前一个类的实例 是后一个类的一种:

>>> obj = unique_ranked_collection() 
>>> isinstance(obj, non_unique_ranked_collection) 
True 

因此,non_unique_collection.overlap()应该接受unique_ranked_collection。

如果您必须强制 unique_collection.overlap() 只接受 unique_ranked_collection,只需重写该方法:

class unique_collection(non_unique_collection): 
 
    # ... 
 
    def overlap(self, other): 
        if not isinstance(other, unique_ranked_collection): 
            raise TypeError('expected an unique_ranked_collection') 
        return super(unique_collection, self).overlap(other)