Wandering Thoughts archives


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. 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 you sometimes do need to know this sort of thing. And per yesterday's entry, 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).

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

python/GettingInterfaces written at 00:19:21; Add Comment

Page tools: See As Normal.
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.