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