pythoninterface-design

Designing an Python API: Fluent interface or arguments


I'm playing around with a simple port of the Protovis API to Python.

Consider the simple bar chart example, in Javascript:

var vis = new pv.Panel()
    .width(150)
    .height(150);

vis.add(pv.Bar)
    .data([1, 1.2, 1.7, 1.5, .7, .3])
    .width(20)
    .height(function(d) d * 80)
    .bottom(0)
    .left(function() this.index * 25);

vis.render();

I'm debating whether to continue to use this fluent interface style API or use named parameters instead. With named parameters we could write:

vis = pv.Panel(width=150,
               height=150)

vis = vis + pv.Bar(data=[1, 1.2],
                   width=20,
                   height=lambda d: d * 80,
                   bottom=0,
                   left=lambda: self.index * 25)
vis.render()

Is there a preferred Python style?


Solution

  • My vote is anti-chaining, pro-named-params.

    1. dot-chaining makes for poor code-intellisense since the empirical prototype is just an empty Panel() or Bar(), you can of course pydoc on it, but in this day and age intellisense is available in most IDEs and a great productivity booster.

    2. Chaining makes programatically calling the class much more difficult. It's very nice to be able to pass in a list or dict as *args, **kwargs -- while possible with chaining you'd basically have to support both methods or a bunch of backflips to meta-create the class.

    3. Chaining makes code more difficult to read because inevitably someone will do it all on one line, and wonder why things are all goofed up when they've passed in the same param twice -- you can prevent that but with a named param constructor dup filtering is basically built in.