Hello. I just joined the list as the whole Abstract Base Class, Interfaces, and Roles/Traits system is of significant interest to me. I've tried to catch up on the discussion by reading through the archives, but I'm sure I missed a few posts and I apologize if I'm wasting time covering ground that's already been covered.
I have a lengthy post that dissects a major issue that I have with ABCs and the Interface definition that I saw in PEP 3124:: it all seems rigidly class and class-instance based. The cardinal sin I saw in the Interface definition in PEP 3124 (at least, at the time I last viewed it) was the inclusion of 'self' in a method spec. It seems to me that Abstract Base Classes and even PEP 3124 are primarily focused on classes. But in Python, "everything is an object", but not everything is class-based. Jim Fulton taught me a long time ago that there are numerous ways to fulfill a role, or provide an interface. 'self' is an internal detail of class-instance implementations. In my post, I show some (stupid) implementations of the 'IStack' interface seen in PEP 3124, only one of which is the traditional class - instance based style. http://griddlenoise.blogspot.com/2007/05/abc-may-be-easy-as-123-but-it-cant-beat.html The rest of this post focuses on what `zope.interface` already provides - a system for specifying behavior and declaring support at both the class and object level - and 'object' really means 'object', which includes modules. You're more than welcome to tune out now. My main focus is on determining what Abstract Base Classes and/or PEP 3124's Interfaces do better than `zope.interface` (if anyone else is familiar with that package). I've found great success using `zope.interface` to satisfy many of the requirements and issues that these systems may try to solve, and more. In fact, `zope.interface` is closer to Roles/Traits than anything else. # ..... I wanted to chime in here and say that `zope.interface` (from Zope 3, but available separately) is an existing implementation that comes quite close to what Collin Winter proposed. Even in some of its spellings. http://cheeseshop.python.org/pypi/zope.interface/3.3.0.1 The main thing is that `zope.interface` focuses declaration on the object - NOT the class. You do not use `self` in interface specifications. Terms I've grown fond of while using `zope.interface` are "specifies", "provides", and "implements". An Interface **specifies** desired *object behavior* - basically it's the API:: class IAuthVerification(Interface): def verify(invoice_number, amount): """ Returns an IAuthResult containing status information about success or failure. """ An *object* **provides** that behavior:: >>> IAuthVerification.providedBy(authorizer) True >>> result = authorizer.verify(invoice_number='KB125', amount=43.40) Now, a class may **implement** that behavior, which is a way of saying that "instances of this class will provide the behavior": class AuthNet(object): def verify(self, invoice_number, amount): """ ... (class - instance based implementation) """ classImplements(AuthNet, IAuthVerification) >>> IAuthVerification.providedBy(AuthNet) False >>> AuthNet.verify(invoice_number='KB125', amount=43.40) <UnboundMethod Exception> Alternatively, class or static methods could be used: class StaticAuthNet(object): @staticmethod def verify(invoice_number, amount): """ ... """ alsoProvides(StaticAuthNet, IAuthVerification) >>> IAuthVerification.providedBy(StaticAuthNet) True >>> result = StaticAuthNet.verify(invoice_number='KB125', amount=43.40) Or a module could even provide the interfaces. In the first example above (under 'an object **provides** that behavior'), do you know whether 'authorizer' is an instance, class, or module? Hell, maybe it's a function that has 'verify' added as an attribute. It doesn't matter - it fills the 'IAuthVerification' role. In my blog post, I also show a dynamically constructed object providing an interface's specified behavior. An instance of an empty class is made, and then methods and other supporting attributes are attached to this specific instance only. Real world examples of this include Zope 2, where a folder may have "Python Scripts" or other callable members that, in effect, make for a totally custom object. It can also provide this same behavior (in fact, I was able to take advantage of this on some old old old Zope 2 projects that started in the web environment and transitioned to regular Python modules/classes). In any case, there are numerous ways to fulfill a role. I think any system that was limited to classes and involved 'issubclass' and 'isinstance' trickery would be limiting or confusing if it started to be used to describe behaviors of modules, one-off objects, and so on. -- Jeff Shell _______________________________________________ Python-3000 mailing list [email protected] http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com
