zoukankan      html  css  js  c++  java
  • python 中接口的实现

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

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

    因此就有了zope.interface的诞生。

    定义接口

    继承 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 'zope.interface.interface.InterfaceClass'>
    
    >>> class A(object):
    	pass
    
    >>> type(A)
    <type 'type'>
    

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

    2. 行为有点类似于字典

    >>> list(IFoo)
    ['x', 'bar']
    >>> IFoo.get('bar')
    <zope.interface.interface.Method object at 0x0000000002B7B710>
    >>> 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 "<pyshell#85>", line 1, in <module>
        IFoo['bar'](1)
      File "C:Python27libsite-packageszopeinterfaceinterface.py", line 616, in __call__
        raise BrokenImplementation(self.interface, self.__name__)
    BrokenImplementation: An object has failed to implement interface <InterfaceClass __main__.IFoo>
    
            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 "<pyshell#13>", line 1, in <module>
        verifyObject(IFoo, Foo())
      File "C:Python27libsite-packageszopeinterfaceverify.py", line 105, in verifyObject
        return _verify(iface, candidate, tentative, vtype='o')
      File "C:Python27libsite-packageszopeinterfaceverify.py", line 62, in _verify
        raise BrokenImplementation(iface, name)
    BrokenImplementation: An object has failed to implement interface <InterfaceClass __main__.IFoo>
    
            The x attribute was not provided.
            
    >>> verifyClass(IFoo, Foo)
    
    Traceback (most recent call last):
      File "<pyshell#14>", line 1, in <module>
        verifyClass(IFoo, Foo)
      File "C:Python27libsite-packageszopeinterfaceverify.py", line 102, in verifyClass
        return _verify(iface, candidate, tentative, vtype='c')
      File "C:Python27libsite-packageszopeinterfaceverify.py", line 62, in _verify
        raise BrokenImplementation(iface, name)
    BrokenImplementation: An object has failed to implement interface <InterfaceClass __main__.IFoo>
    
            The bar attribute was not provided.
    

      

    b) 用实例变量实现:

    >>> b= Foo()
    >>> b = zope.interface.implementer(IFoo)(b)
    >>> list(zope.interface.providedBy(b))
    [<InterfaceClass __main__.IFoo>]
    

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

    >>> from zope.interface import implementer
    >>> @implementer(IFoo)
    class Foo:
    	pass
    
    >>> list(zope.interface.implementedBy(Foo))
    [<InterfaceClass __main__.IFoo>]
    

      

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

    >>> list(zope.interface.implementedBy(Foo))
    [<InterfaceClass __main__.IFoo>]
    

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

    >>> IFoo.implementedBy(Foo)
    True

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

    >>> list(zope.interface.providedBy(f))
    [<InterfaceClass __main__.IFoo>]
    

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

    >>> 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
    

      

  • 相关阅读:
    plink:将bed文件转化为ped,map文件
    linux下查找某文件关键字(grep 函数)
    genetic model
    linux下设置默认路径
    vi怎么查找关键字
    有意思的undefined columns selected,源于read.table和read.csv
    练习2-2
    练习2-1
    排序算法之堆排序
    Java实现二叉树先序,中序,后序,层次遍历
  • 原文地址:https://www.cnblogs.com/Tommy-Yu/p/4097607.html
Copyright © 2011-2022 走看看