PythonLanguage doesn't have interfaces like
JavaInterfaces. If it's for
MultipleInheritance, Python already has it, but for "contract compliance" it hasn't.
Not built-in, but
ZopeApplicationServer has an 'interfaces' module that does pretty much everything you could want. The Twisted framework for
AsynchronousProgramming also has a usable implementation of interfaces as regards contract compliance. --
MoeAboulkheir
There is a PEP for implementing Interface Syntax in Python. It's PEP-245 at
http://www.python.org/peps/pep-0245.html.
It would be very nice when it's implemented, but it still can't guarantee the semantics (pre/post-conditions, and invariants) even if it's implemented. Yes, you should follow the documentation very carefully. If you are a good programmer it won't be any problem but if you are a rogue or novice programmer, what happens?
If you're a rogue programmer, your code is going to stink anyway. If you're a novice, what are you doing bungling around with interfaces?
I do use
UnitTests extensively when programming and apply them to interfaces compliance checking as well.
You know interfaces sometimes can deceive you -- it could be fictitious without semantic guarantee. With
UnitTests, however, the interfaces can guarantee semantics as well.
The following code will tell, (If the client implements Stack
Interface with List
Stack, she'll make a unittest module for that and name it "test_StackList". In the test, she just imports all the tests from Stack
Interface so that interface compliances are guaranteed. She might add some List
Stack-specific test cases in the same module test_StackList.)
#------------------------------------------------
#StackInterface.py
import unittest
class StackInterface: #or put this whole class as a doc string
'''Anything that implements this should pass the unittests in
StackInterface with its own MyImpl
'''
def push(self, anObject):
raise NotImplementedError
def pop(self):
raise NotImplementedError
def isEmpty(self):
raise NotImplementedError
class _Object: #helper object representing _anything_
pass
class TestStackInterface(unittest.TestCase):
def setUp(self):
self.stack=MyImpl()
def testPushAndPop(self):
o=_Object()
self.stack.push(o)
self.assertEqual(o, self.stack.pop())
def testPopOnEmpty(self):
self.assert_(self.stack.isEmpty())
self.assertRaises(IndexError,self.stack.pop)
def testPushAllAndPopAll(self):
oList=[_Object() for i in range(10)]
for each in oList:
self.stack.push(each)
oList.reverse()
for each in oList:
self.assertEqual(each, self.stack.pop())
MyImpl=StackInterface #please override this with the real implementation
if __name__=='__main__': # you won't run this module directly though
unittest.main()
#------------------------------------------------
#ListStack.py
from StackInterface import StackInterface
class ListStack(StackInterface):
def __init__(self):
self._s=[]
def push(self, anObject):
self._s.append(anObject)
def pop(self):
return self._s.pop()
def isEmpty(self):
return len(self._s)==0
#------------------------------------------------
#test_ListStack.py
import unittest
import StackInterface
from ListStack import ListStack
StackInterface.MyImpl=ListStack
from StackInterface import * #if you want to implement several
#interfaces just import all of them here
if __name__=='__main__':
unittest.main()
--
JuneKim
CategoryInterface CategoryPython