我经常看到这样实现的类,只是想知道为什么?即使它是基类,也不会创建子类可以遵循的接口。
class AnAbstractBaseCLass:
pass
答案 0 :(得分:0)
拥有一个基类,如您显示的子类实例可能与其他非派生类的实例混合在一起,并且您想轻松区分它们一样,可能会很有用。
class Base: pass # empty base class
class Derived1(Base): pass # normally this would have contents, but it's empty for this example
class Derived2(Base): pass
class OtherClass: pass # not derived from Base
mixed_list = [Derived1(), Derived2(), OtherClass()]
filtered_list = [obj for obj in mixed_list if isinstance(obj, Base)]
这可能并没有那么有价值,因为不能保证派生类具有任何公共接口,因此filtered_list
可能无法得到充分利用(因为您无法调用任何接口)。其值的通用方法)。但是可能有,甚至有可能存在一些 通用接口,但这不是基类(使用abc
模块强制执行的任何操作)。
答案 1 :(得分:0)
也许这类似于Java的标记器接口。例如。 RandomAccess
是一个无效接口(没有方法):
List实现使用的Marker接口表示它们支持快速(通常为恒定时间)随机访问。此接口的主要目的是允许通用算法更改其行为,以便在应用于随机或顺序访问列表时提供良好的性能。
列表是否支持快速随机访问不会影响列表的界面,但会影响列表的性能。
更一般地说,接口或基类,作为一组公共方法(无论“ public”在Python中的真正含义是什么),都是一种功能契约,但不涉及非功能性问题(请参见{{ 3}})。大多数时候,我们确切地知道我们使用的对象的类型,但有时由于多态性,我们不知道。但是我们可能需要一些非功能性信息,而空基类可能是一个很好的解决方案:
if isinstance(L, RandomAccess):
# I can use L[i] without performance penalty
else:
# I will use an iterator