. Python 2.1 function attributes

Alex Martelli aleaxit at yahoo.com
Mon Feb 5 17:20:45 CET 2001

"Toby Dickenson" <mbel44 at dial.pipex.net> wrote in message
news:1jct7tg5u6j3fir09edclfm5jmf5n59eto at 4ax.com...
> >The redirection minuet is one thing, but I claim that write
> >with a %-format doesn't leave me wanting for decent ways to
> >do output.  A printlike function would be better, but I
> >don't hunger for it often, because write-plus-% does it well;
> Not well enough, apparently, judging by the number of packages that
> grew out of the need for exactly this type of output. A need that
> wasnt satisfied by file.write("formatting"%(data))

Oh, of course, there ARE plenty of human-readable-output needs
that neither file.write, nor print in any form, support decently.

You mention HTML-oriented templating output, which has no special
need to be human-readable: there, file.write with format is _much_
superior, since more easily localized (print is a disaster in this
sense -- no problem for quick&dirty debug-oriented output, but of
course NOBODY is writing deliberately non-localizable applications,
*ARE THEY*...?-); but 'full templating' is often more powerful, and
it's simple to implement well in Python, too -- so, like everybody
else, I built my own "Yet Another Python Template Utility" (YAPTU)
and use that one for those (not-infrequent) text-output needs that
are well satisfied via templating.

_Some_ output needs require more logic than such templating can
supply while remaining simple and well-usable.  Hierarchical stuff
that nests to arbitrary depth, for example; I know of no template
solution that fully supports the unlimited-depth recursion that is
typical (e.g.) of some ways to present a "bill of materials".  For
THAT, the recursive logic is better handled in Python (IMHO).  But
when the time comes to output a given 'block' of info (typically a
line or small block of lines, with the code-logic determining, e.g.,
to what 'depth' it is to be indented), the specifics are still best
handled with a formatting-line (with a dictionary on the RHS of the
%, no doubt, and named fields -- we ARE talking about somewhat
complicated needs after all!), and that formatting line had better
be retrieved by reasonably flexible logic, else, one can wave
good-bye to localization and customization (fortunately, a DB tends
to be around when one is doing stuff at THIS level of complexity,
so, a way is not lacking to flexibly store and recoved the needed

> The real problem (IMO) with file.write("formatting"%(data)) is that
> the expressions that build up the data are out of line with the static
> content. Its harder for the programmer to visualize the bigger picture
> of his output, because he has to mentally interleave the dynamic and
> static parts. The problem is greater in functions whose only job is
> output formatting.

If the ONLY job is output formatting, then there are going to be
no 'expressions' to speak of -- 'data' will be a dictionary that
associates names with values, and the computation will have been
done elsewhere -- a very sensible way to split computation from
presentation tasks, of course.  But then, where is the difference
between, e.g.,

flob.write("An a %(one)s an a %(two)s an a %(three)s!\n" % data)


print >> flob, "An a",one,"an a",two,"an a",str(three)+"!"

except the sundry ways in which the second form is inferior?

E.g., it's trouble to get the final '!' adjacent to the last
item being output (you need to switch to str and concatenation
rather than using the same approach as for all other items),
localization is a bear (how do you get the pieces, how many
do you get, how do you order the items...?), so is formatting
to align columns to the left or right (trivial with %), the
function itself needs to know the names of the items and get
them into its namespace appropriately, AND flob itself may
get several write calls and softspace settings and queries
rather than dealing with just one nice solid write period.

> The disadvantage is comparable to the difference between using an
> infix notation, or function notation for arithmetic.

It's true that a few more parentheses are needed for a write
call, since Python syntax requires them (both around the
whole %-expression, and inside the format-string when the
RHS is a dictionary).  But print>> requires a similar amount
of commas, so it balances out; the _order_ in which the
names are used is the same, and there are no "function names"
vs "operators" involved, so the analogy is strained.

> ps. Ive used both dtml and quixote templates, but largely abandonned
> them both in favor of print >>

If templates were not suitable for your needs, you no doubt
did well to abandon their use.  But using fileob.write rather
than print>>fileob would have ensured further benefits -- see
above.  So, your choice need not have been the optimal one.

Betraying the "one obviously correct way" philosophy is just
one more way in which 'print>>' is unPythonic.  There never
really IS just one way, of course, nor is the right one, often,
"obviously" right; but providing one more way to do yet the
same thing -- particularly one whose disadvantages (difficulty
in localization, column alignment, etc, etc) may not be obvious
to inexperienced users -- was a step in the wrong direction.

(Reflecting on how all needs might have been best served -- a
futile exercise, some would say, but I'm a Santayana follower --
leads me to believe that a Print function [also supplied as a
method on built-in objects -- much like xreadlines is going to
be both a method of built-in objects AND a utility function to
wrap user-written objects, if I understand that correctly] would
have been Just Right.  It would take an optional 'format='
argument, which, if present and not None, overrides the implicit
``formatting'' of "paste stuff together with spaces and a \n
and the end"; one could easily prototype with a call to Print
almost identical to today's print statement, then add to it a
suitable format= for localization, just as one might add a
suitable file= etc.).


More information about the Python-list mailing list