changeset 550:9149b35b8a2a

python/example/abstract.py
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 18 Nov 2013 16:17:39 -0800
parents 3168816f2d28
children 029c7c2c511d
files python/example/abstract.py
diffstat 1 files changed, 65 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/python/example/abstract.py	Mon Nov 18 11:28:30 2013 -0800
+++ b/python/example/abstract.py	Mon Nov 18 16:17:39 2013 -0800
@@ -1,3 +1,10 @@
+#!/usr/bin/env
+
+"""
+demo related to abstract classes
+"""
+
+### roll our own to demo
 
 def abstractmethod(method):
     line = method.func_code.co_firstlineno
@@ -21,7 +28,33 @@
     def foo(self, arg):
         print 'hello'
 
+
+### now use the abc module
+
+import abc
+
+class AbstractClass(object):
+    @abc.abstractmethod
+    def foo(self, arg):
+        """blah"""
+    @abc.abstractmethod
+    def bar(self):
+        """bar does nothing"""
+
+class CementClass(AbstractBaseClass):
+    def foo(self, arg):
+        print 'goodbye'
+
+class Picasso(object):
+    __metaclass__ = abc.ABCMeta
+    @abc.abstractmethod
+    def foo(self, arg):
+        """blah"""
+
+
 if __name__ == '__main__':
+
+    # home-rolled
     c = ConcreteClass()
     c.foo(1)
     a = AbstractBaseClass()
@@ -34,6 +67,37 @@
     except NotImplementedError, e:
         print e
     c.foo(1)
-    a.foo(1)
+    try:
+        a.foo(1)
+    except NotImplementedError, e:
+        print e
 
+    ### abc
+    print '\nIllustrate `abc` functionality'
+    a = AbstractClass()
+    e = None
+    try:
+        a.foo(1)
+        # you'd think this would raise an exception since`
+        # `AbstractClass.foo` is decorated with `abc.abstractmethod`
+        # But see http://docs.python.org/2/library/abc.html :
+        # "Using this decorator requires that the class's metaclass
+        # is ABCMeta or is derived from it."
+    except Exception, e:
+        pass
+    assert e is None # !
 
+    # as an aside, another good reason not to use super:
+    # "Unlike Java abstract methods, these abstract methods may
+    # have an implementation. This implementation can be called via the super()
+    # mechanism from the class that overrides it. This could be useful as
+    # an end-point for a super-call in a framework that uses cooperative
+    # multiple-inheritance."
+
+    a = Picasso()
+    e = None
+    try:
+        a.foo(1)
+    except Exception, e:
+        pass
+    import pdb; pdb.set_trace()