扩展列表可能不好的一个原因是因为它将“MagicReport”对象与列表紧密联系在一起.例如,Python列表支持以下方法:
append
count
extend
index
insert
pop
remove
reverse
sort
它还包含许多其他操作(添加,使用<和>,切片等进行比较).
所有这些操作都是你的’MagicReport’对象真正想要支持的吗?例如,以下是合法的Python:
b = [1, 2]
b *= 3
print b # [1, 2, 1, 2, 1, 2]
这是一个非常人为的例子,但是如果你从’list’继承,你的’MagicReport’对象会做同样的事情,如果有人无意中做了这样的事情.
再举一个例子,如果你尝试切割MagicReport对象怎么办?
m = MagicReport()
# Add stuff to m
slice = m[2:3]
print type(slice)
您可能希望切片是另一个MagicReport对象,但它实际上是一个列表.你需要覆盖__getslice__以避免令人惊讶的行为,这有点痛苦.
它还使您更难以更改MagicReport对象的实现.如果您最终需要进行更复杂的分析,那么通常可以将基础数据结构更改为更适合问题的结构.
如果你是list的子类,你可以通过提供新的append,extend等方法解决这个问题,这样就不会改变接口,但是你没有任何明确的方法来确定哪个列表方法实际上是除非你仔细阅读整个代码库,否则使用它.但是,如果您使用合成并只将列表作为字段并为您支持的操作创建方法,则您确切知道需要更改的内容.
我实际上遇到了一个与你最近的工作非常相似的场景.我有一个对象,其中包含我首先在内部表示为列表的“事物”集合.随着项目要求的变化,我最终将对象更改为内部使用dict,自定义集合对象,最后是快速连续的OrderedDict.至少根据我的经验,组合使得更改某些内容的实现变得更容易,而不是继承.
话虽这么说,我认为扩展列表可能适用于你的’MagicReport’对象合法地除了名称之外的所有列表的情况.如果您确实希望将MagicReport用作每个方向的列表,并且不打算更改其实现,那么它可能更方便子类列表并且只是完成它.
虽然在这种情况下,最好只使用一个列表并编写一个“报告”函数 – 我无法想象您需要多次报告列表的内容,并使用自定义方法创建自定义对象仅仅为了这个目的可能是矫枉过正(虽然这显然取决于你究竟想要做什么)