Christian Convey a écrit : > Perhaps I'm deluded but I don't think so.
<after what='having read the rest of the post'>. You are. </after> > I'll tell you my situation > and I'd appreciate your take on it... > > I'm looking into the design a network simulator. The simulator has a > few requirements: > > (1) I need to be able to swap in a variety of replacement components > during different simulations. I.e., RadioFrequencyChannelModel, > WiredNetworkChannelModel, etc. This drives me to want the notion of > inherited interfaces, partly as a form of documentation. Ok. > (2) I want a form of encapsulation (which I realize isn't necessarily > guaranteed in all possible static typing implementations). I.e., I want > to ensure that any code which accesses a ChannelModel only calls those > methods that are part of the ChannelModel interface. If there's a > method RadioFrequencyChannelModel.setBroadcastDistance(...), which isn't > part of the generic ChannelModel interface, I don't want most of my code > to be able to start using that particular method, if the code need to be > able to work with all possible ChannelModel implementations. This is mostly a self-discipline issue. But FWIW, unit-testing should be enough here. And if you really want something more bondage-and-discipline, you can use some wrapper object to filter out the exposed interface. There's very few to do - here's a possible (while mostly dumb) home-made solution: class InterfaceType(type): def __new__(meta, class_name, bases, new_attrs): cls = type.__new__(meta, class_name, bases, new_attrs) cls._exposed = [name for name in new_attrs.keys() \ if not name.startswith('_')] return cls class Interface(object): __metatype__ = InterfaceType @classmethod def _expose(cls, name): return name in cls._exposed class InterfaceRestrictor(object): def __init__(self, obj, interface): self._interface = interface self._obj = obj def __getattr__(self, name): if self._interface._expose(name): return getattr(self._obj, name) else: raise AttributeError("name %s not allowed" % name) And you can use a decorator specifying arg names or types -> expected interface to automagically ensure you get correctly wrapped objects in the client code. NB : Don't use that code - here again, object-adaptation (which is at the core of Zope3 interfaces and Peak's Protocols) comes to mind... > (3) I like Interfaces as a matter of documentation. It helps me to > thing things through. I've got a lot of components that must support > interchangeable implementations: BTW, did I suggest to have a look at Zope3 interface or Peak's protocols ?-) > channels, modems, MAC layers, link > layers, etc. If I have an abstract MAC_layer interface, it helps me > think carefully about what every MAC layer ought to provide, and it also > helps me explain to other people what a MAC layer in my simulator must > provide. That is, it helps me better explain to other people how the > system's major components relate to each other. Ok, now this is a design issue. All you need here is an UML-aware drawing program. > Now, I could use Java or C# to get functionality such as interfaces, but > I loath giving up the general productive goodness of Python. That's why > I'm looking for something like interfaces. Given your motivations and requirements (which seems pretty sensible AFAIC), you definitively want to have a look at Zope3 Interfaces or Peak Protocol. They'll give you *much* more than Java's interfaces. > But even if we disagree about the wisdom of my intentions, We don't. The point on which we disagree is the proposed solution !-) > do you know > if/when Guido's planning to work that stuff into Python? The last post > I noticed from him on the topic was from 2005. At least back then he > sounded pretty into it. I don't think this will ever make it into Python. But you really don't need it anyway. Well, IMHO at least !-) -- http://mail.python.org/mailman/listinfo/python-list