2022年 11月 5日

python 接口实现_python 中接口的实现

实际上,由于python是动态语言,支持多继承,因此接口在语言层面,是没有的东东。

然后,在架构设计上,我们又需要这么一个东西,来规范开发人员的行为。

定义接口

继承 zope.interface.Interface即可,如下:

import zope.interface

class IFoo(zope.interface.Interface):

“””Foo blah blah”””

x = zope.interface.Attribute(“””x blah blah”””)

def bar(q, r=None):

“””bar blah blah”””

1. 接口不是类

>>> type(IFoo)

>>> class A(object):

pass

>>> type(A)

但能正常访问:__dict__ / __name__ / __module__ / __doc__ 等专有属性

2. 行为有点类似于字典

>>> list(IFoo)

[‘x’, ‘bar’]

>>> IFoo.get(‘bar’)

>>> callable(IFoo.get(‘bar’))

True

3. 接口中的方法能自动获取签名

>>> IFoo[‘bar’].getSignatureString()

‘(q, r=None)’

实现接口

在声明接口之前,有两个术语要说明下:

provide(提供接口)

对象实例(object)提供接口,接口详细描述/规范了对象的行为。

implement(实现)

类(可以抽象成工厂类)实现(implement)接口。

类一般不会提供(provide)接口。只有对象提供接口。【备注:此处属于术语概念,了解即可】

1. 实现接口:

a). 用类实现

>>> class Foo:

zope.interface.implements(IFoo)

有点诧异:没有报错!对象实例呢?

>>> f = Foo()

也没有报错!然后下面却报错了:

>>> IFoo[‘bar’](1)

Traceback (most recent call last):

File “”, line 1, in

IFoo[‘bar’](1)

File “C:\Python27\lib\site-packages\zope\interface\interface.py”, line 616, in __call__

raise BrokenImplementation(self.interface, self.__name__)

BrokenImplementation: An object has failed to implement interface

The bar attribute was not provided.

问题:该如何在子类的实例中使用接口里面定义的方法?

如何规范开发人员的行为?

答案是:通过测试来发现对象或者类是否实现了定义的接口。通过代码测试来做。通过测试控制开发,似乎有点马后炮。

主要使用 zope.interface.verify 里面的 verifyObject 和 verifyClass方法。可以参考这里。

>>> class IFoo(Interface):

x = Attribute(“The X attribute”)

def bar(q,r=None):

“””bar of interface”””

>>> class Foo:

implements(IFoo)

>>> from zope.interface.verify import verifyObject, verifyClass

>>> verifyObject(IFoo, Foo())

Traceback (most recent call last):

File “”, line 1, in

verifyObject(IFoo, Foo())

File “C:\Python27\lib\site-packages\zope\interface\verify.py”, line 105, in verifyObject

return _verify(iface, candidate, tentative, vtype=’o’)

File “C:\Python27\lib\site-packages\zope\interface\verify.py”, line 62, in _verify

raise BrokenImplementation(iface, name)

BrokenImplementation: An object has failed to implement interface

The x attribute was not provided.

>>> verifyClass(IFoo, Foo)

Traceback (most recent call last):

File “”, line 1, in

verifyClass(IFoo, Foo)

File “C:\Python27\lib\site-packages\zope\interface\verify.py”, line 102, in verifyClass

return _verify(iface, candidate, tentative, vtype=’c’)

File “C:\Python27\lib\site-packages\zope\interface\verify.py”, line 62, in _verify

raise BrokenImplementation(iface, name)

BrokenImplementation: An object has failed to implement interface

The bar attribute was not provided.

b) 用实例变量实现:

>>> b= Foo()

>>> b = zope.interface.implementer(IFoo)(b)

>>> list(zope.interface.providedBy(b))

[]

在python 2.6后,可以直接用修饰符,上面代码的等同代码如下:

>>> from zope.interface import implementer

>>> @implementer(IFoo)

class Foo:

pass

>>> list(zope.interface.implementedBy(Foo))

[]

2. 查看类实现了哪些接口

>>> list(zope.interface.implementedBy(Foo))

[]

测试某接口是否由某类实现:

>>> IFoo.implementedBy(Foo)

True

3. 查看对象实例实现了哪些接口

>>> list(zope.interface.providedBy(f))

[]

测试某接口是否由某对象提供

>>> IFoo.providedBy(f)

True

接口的继承

与python的类继承相似。又有所不同,接口继承不是深度优先,如下:

>>> import zope.interface

>>> class IBase(zope.interface.Interface):

def foo():

“””base foo doc”””

>>> class IBase1(IBase):

pass

>>> class IBase2(IBase):

def foo():

“””base2 foo doc”””

>>> class ISub(IBase1, IBase2):

pass

>>> ISub[‘foo’].__doc__

‘base2 foo doc’

类的继承:

>>> class Base:

def foo(self):

print “base”

>>> class Base1(Base):

pass

>>> class Base2(Base):

def foo(self):

print “base2”

>>> class Sub(Base1,Base2):

pass

>>> Sub().foo()

base