我想以某种方式使用python程序解析Apache access.log文件,虽然我对面向对象编程完全不熟悉,但我现在想开始这样做.
我将创建一个类ApacheAccessLog,而我现在唯一想象的就是' readline '方法.在这种情况下,从内置文件类继承是否通常正确,因此该类的行为就像文件类本身的实例一样,是不是?这样做的最佳方式是什么?
在这种情况下,我会使用委托而不是继承.这意味着您的类应该包含文件对象作为属性并readline
在其上调用方法.您可以在logger类的构造函数中传递文件对象.
至少有两个原因:
委托减少了耦合,例如代替文件对象,您可以使用任何其他实现readline
方法的对象(鸭子输入在这里很方便).
从文件继承时,您的类的公共接口变得不必要地广泛.它包括在文件中定义的所有方法,即使这些方法在Apache日志中没有意义.
我来自Java背景,但我相信相同的原则将适用于Python.作为一个经验法则,你应该永远不会从一个类,其实现你不理解和控制,除非这个类已经继承专门设计继承.如果它是以这种方式设计的,它应该在其文档中清楚地描述.
原因是继承可能会将您绑定到您继承的类的实现细节.
使用Josh Bloch的书"Effective Java"中的一个例子
如果我们要扩展类ArrayList
类以便能够计算在其生命周期中添加到它的项目数(不一定是它当前包含的数量),我们可能会想要写这样的东西.
public class CountingList extends ArrayList { int counter = 0; public void add(Object o) { counter++; super.add(0); } public void addAll(Collection c) { count += c.size(); super.addAll(c); } // Etc. }
现在,这个扩展看起来会准确计算添加到列表中的元素数量,但事实上它可能没有.如果通过遍历提供的方法并为每个元素调用其接口方法来ArrayList
实现addAll
,那么我们将计算通过该方法添加的每个元素两次.现在我们类的行为依赖于实现细节.Collection
addAll
addAll
ArrayList
这当然是除了不能使用List
我们CountingList
班级的其他实现的缺点之外.再加上从上面讨论的具体类继承的缺点.
据我所知,Python使用与Java类似(如果不相同)的方法调度机制,因此会受到相同的限制.如果有人能在Python中提供一个例子,我相信它会更有用.