self.__class__
是对当前实例的类型的引用。
对于abstract1
的实例,它将是abstract1
类本身,这不是您想要的抽象类。抽象类只能被继承,不能直接创建实例:
>>> abstract1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
NotImplementedError: Interfaces can't be instantiated
对于abstract1
的一个子类实例,self.__class__
将引用特定的子类:
>>> class Foo(abstract1): pass
...
>>> f = Foo()
>>> f.__class__
<class '__main__.Foo'>
>>> f.__class__ is Foo
True
在这里抛出异常就像在代码的其他地方使用断言语句一样,它可以保护您免受犯傻瓜错误的困扰。
请注意,测试实例类型的“Pythonic”方式是使用
type()
函数,结合使用
is
运算符进行身份测试:
class abstract1(object):
def __init__(self):
if type(self) is abstract1:
raise NotImplementedError("Interfaces can't be instantiated")
type()
应该优先于 self.__class__
,因为后者可能会被类属性遮盖。
在这里使用等式测试没有多大意义,因为对于自定义类,__eq__
基本上实现为一个身份测试。
Python 还包括一个标准库来定义抽象基类,称为abc
。它允许您将方法和属性标记为抽象,并拒绝创建任何尚未重新定义这些名称的子类的实例。