== Finally understanding the appeal of 'Interfaces' I spent a long time not really getting the need for coded, explicit implementations of 'Interfaces', by which I mean things like [[zope.interface http://wiki.zope.org/Interfaces/FrontPage]]. It didn't help that I generally encountered them as part of very large, complex systems like Zope and Twisted, and they tended to come with a lot of extra magic features, which made the whole idea seem like the sort of thing you only needed if you had to deal with such a beast. Then, recently, the penny dropped and I finally saw the light. Shorn of complexity and extra features, ~~what Interface implementations give you is an explicit and easily used way to assert and ask 'is-a' questions~~. Need to find out if this object is a compiled regular expression? Just ask if it supports the ICRegexp interface. What to be accepted as a compiled regular expression? Assert that you support ICRegexp. (Assuming the best and forging ahead is still the most Pythonic approach, but [[per my original problem ExposeYourTypes]] you sometimes do need to know this sort of thing. And [[per yesterday's entry InheritanceVsInterface]], requiring inheritance is not the answer, especially if you want to build decoupled systems.) When I put it this way, it's easy to see why you'd like a basic interface implementation. If you have to test at all, simple 'is-a' tests beat both 'is-a-descendant-of' restrictions and probing for duck typing with its annoyances and ambiguities (cf [[an earlier entry DuckTypingLimits]]). In this view, the important thing is really to have a unique name (really an object) for each interface, so that you avoid the [[duck typing ambiguity DuckTypingLimits]]. A basic implementation is almost trivial; treat interfaces as opaque objects, and just register classes as supporting interfaces and then have an '_isinterface()_' function that works by analogy to _isinstance()_. (This demonstrates the old computer science aphorism that there's no problem that can't be solved by an extra level of indirection, since that is basically what this does: it adds a level of indirection to _isinstance()_, so that instead of asking 'is this object an instance of one of these classes', you ask 'is this object an instance of a class that supports this interface'.) More complex implementations are of course possible; you could give the interface objects actual behavior and information, add checks for basic duck typing compatibility with the interface, make it so that _isinterface()_ can optionally check to see if the object seems to implement the interface without having declared it, and so on. (Sooner or later you end up back at [[zope.interface]].)