假设有人为您提供了一对可以协同工作的现有课程:
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
或{{1}一起使用和unique_collection
(但不在unique_ranked_collection
和unique...
类型之间)?我开始使用non_unique...
添加一些断言语句,但它看起来很混乱,我想征求意见。
我能想到的最好的事情是拥有两个isinstance
和unique...
类型继承的基类。你怎么看待这个?
非常感谢。
PS--我知道代码编写的这个特定问题非常无趣,但它只是一个例子。
答案 0 :(得分:1)
如果你真的想强制执行此操作,请三思。不推荐对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)
答案 1 :(得分:0)
您可以通过标记类,并在所有类中使用overlap
外部函数而不是方法,明确提及要允许调用overlap
的“类型”。
我认为这不是非常pythonic,因为它试图强制类上的类型,但它们是弱类型,将它们视为“重叠桶”,但它取决于您的实际用例。
另一个问题是,在您的示例中,unique_collection
是 non_unique_collection
(继承自它),同样unique_ranked_collection
是 non_unique_ranked_collection
,这意味着您需要一个复杂的类矩阵来对其进行排序,或使用类似下面的示例:
class non_unique_collection:
type = 'N'
class non_unique_ranked_collection:
type = 'N'
class unique_collection(non_unique_collection):
type = 'U'
class unique_ranked_collection(non_unique_ranked_collection):
type = 'U'
def overlap(collection1, collection2):
if collection1.type != collection2.type:
raise TypeError
return True