Status of optional static typing in Python?
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Thu Jun 22 20:47:50 EDT 2006
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 !-)
More information about the Python-list
mailing list