假设有人给了你一对现有的协同工作的类:
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)
