UML and Python

Terry Hancock hancock at anansispaceworks.com
Wed Jan 22 23:00:48 CET 2003


Terry Hancock wrote:
> Does UML work for Python? 
> Interfaces
> Components
> Acquisitiion
> Pluggable Brains

Thanks for all the useful (even if conflicting) opinions!

I have found the class-diagrams useful for defining my interfaces and 
object model.  After some installation frustrations, I opted to stick with 
dia, at least for now.   I'm using a newer version (0.88.1) than before 
which doesn't segfault on me (at least not so far).  Looks like this will 
be good enough for the paper I'm writing.

I opted to represent interfaces (using Zope's interface/component model) as 
"abstract classes with stereotype 'interface'", "implemented by" a concrete 
class.  I also use the naming convention of:

LumAPI -- an interface specification
Lum       -- the simplest or most obvious implementation of LumAPI that
                 actually works.
NonLum -- a null-implementation that pretends to work, but does nothing
                  useful (sometimes useful as a placeholder).
Elle        -- Can use other names to represent different / less-obvious
                  implementations of the same API.

ReiAPI    -- can be a pluggable brain API, in which case the stereotype is
                  "interface/PB"
ReiPB   -- a "pluggable brain" implementation class.  I borrowed the
                "document" symbol from the "flowchart" package to document
                 what record/query the PB extends.
Rei       -- an DB querying object that provides methods to access the
                database table. The query methods return a "list of ReiPB".

This is a bit briefer than "Lum"=interface, 
"LumImplementation"=implementation, which is what the Zope product DevGuide 
has.  I also find it more descriptive, since "the thing itself" has the 
more basic name, while the more removed symbol of the thing has a modified 
name letting you know what it is.

However, rather than focusing on objects or even classes, I'm focusing on 
the interfaces.  If an interface A "contains" another interface B as an 
attribute b, that means that "an object implementing interface A must 
contain A.b which implements interface B".  That's nice, because in 
principle, the interface doesn't care what sort of objects A & B are, so 
long as they exhibit the correct behavior ("polymorphism"?). To make this 
work still better, I'm going to have to replace my "meta-type" checks in 
Zope with "implements" checks.

Since I don't list methods or attributes that are already specified by the 
interface, I wind up with implementation classes being nothing more than a 
name in a box, for the most part, with one or more "implements" arrows, 
with only a very few exceptions.

Acquisition has to do with the deployment of class instances, and I haven't 
tackled that yet, so I'm not positive how I'll do it.

Another uniquely Python trick that I will need to use "stereotypes" for is 
the "monkeypatch" arrow where a live object is modified by adding an 
attribute at runtime. An admittedly dangerous technique, but sometimes 
necessary, and I don't think you can do it in other languages. ;-)

One thing I like about this process, is that an overblown API shows up like 
a sore thumb, which encourages me to find ways to simplify.  Which is 
really good, because I have a few in my current package that I'm working on 
clearing away now.  Also good for improving the consistency of labels (i.e. 
that the "summary()" method should do something similar when applied to two 
different content objects, even if the whole interface is not copied.).

So I'm having to bend it a little, but UML is still proving fairly useful.

Thanks for the comments!
Terry

-- 
Anansi Spaceworks
http://www.anansispaceworks.com




More information about the Python-list mailing list