. Python 2.1 function attributes

Tim Peters tim.one at home.com
Thu Feb 1 04:34:32 EST 2001


[Tim]
>> ...
>> The testimony of one person who tried a thing and found it
>> lacking is more compelling than 100 virgins speculating about
>> why they're certain they would despise it if only they could
>> bear stooping low enough to try it <wink>.

[Alex Martelli]
> Actual experience with using some tool may be a _part_ of what
> gives 'impressiveness' to reports that said tool is inferior,
> but it's generally not a major component thereof -- e.g., the
> tool may have been misunderstood, misused, etc.

That's important too, though.  That is, if people misunderstand or misuse,
that may point to serious flaws in the docs or the design.  There's just no
substitute for experience.  Not that that's *all* there is, but it's
important.  In this case, we learned that *nobody* misunderstood what it
did.  I suspect some people still take it way too seriously, though (like
reduce, map and lambda, it's meant to be a minor convenience, not a new
foundation on which to build all your file output!  maybe that's a lesson we
failed to learn from reduce & friends).

>> telling fact that Guido rejected Barry's print>> proposal
>> before giving it a test drive in his own code -- pure argument
>> never had much to do with this one.

> Interesting -- I don't recall hearing about this detail previously.

There's a bit of it in the SourceForge patch history:

http://sourceforge.net/patch/index.php?func=detailpatch&patch_id=
    100970&group_id=5470

although there are many gaps in the discussion.  The Python-Dev archives may
or may not have more, but I've really got no interest in reliving this one.

> It _does_ interestingly contradict Guido's posts at the time,
> requesting _arguments_ (NOT "experiences") -- which, to me and I
> guess to other respondents, implied that the requested arguments
> *would* have a bit to do with something; I'm less surprised, now
> that I hear this, that said arguments mattered not a whit.

We need some context here.  Stephen Figgins wrote a great (IMO) "outsider"
summary of the brouhaha at the time:

  http://www.oreillynet.com/pub/a/python/2000/08/30/pythonnews.html

Against the background of "a flurry of posts that accused the Python
development team of creeping featurism, selling out the language to
corporate interests, moving too fast, and turning a deaf ear to the Python
community", Guido was trying to insist on some sanity.  Don't take it
personally, I don't think it was ever directed at you.  But the overall
debate had gone nuts.  As Moshe reminded already, what Guido asked NOT to
get was "votes", not "experience".  A killer pure argument would have been
great too.  However, in his estimation he didn't get one, much as in your
estimation he didn't make one.  So it goes.

> ...
> Oh, I do realize this -- Python *will* have this wart forevermore.
> That doesn't mean I intend to suffer it *silently*.

No indeed, so long as it's understood that the right to speak is not also
the right to be listened to -- don't you think there are more *interesting*
things to do in the Python world than beat this dead horse?  I do.

> ...
> I thought I had posted (must have been 4-5 months ago) about my
> "print>>" experiments?

I could well have missed that -- sorry.  In the crunch to get Python 2.0 out
the door, we were all pulling 20-hour days for a while, and facing the
prospect of being out of work anyway (indeed, as things turned out, we
finished the release on our own time).  It was darned hectic.

> Briefly -- I took one module that was using about 20 print
> statements in two functions (and used the sys.stdout setting for
> redirect when needed, from a separate wrapping function) and
> recoded it using '>>blotch' on every print (with 'blotch' a
> function parameter defaulting to None on the operating functions).

I don't think I would have liked ">>blotch" in that context either:  if I
find myself using print>> in more than one or two lines in a function, I
don't like it.  It's simply too wordy for me then.  It's the bee's knees,
though, for an infrequent print to a rarely-used file, or for echo'ing the
same msg to multiple files (like a log and stdout).  Then it's pleasant.

BTW, I see you also picked up on my dislike for sys.stderr.  In the doctest
context, yes, that's 100% my baby and I wrote it to please me.  I don't have
that luxury when working on other peoples' code, though, and if someone is
already printing to sys.stderr, I'll play along for the sake of keeping
their code true to *their* vision.  And then

   print >> sys.stderr, "Hey! I got", `got`, "but expected", `want`

1 line in 250 is pure pleasure.

> The small wrapper was not bad:
>
> from [before 'print>>']:
>
> def foobarRedirect(fileob, *args):
>     save = sys.stdout
>     try: return foobar(*args)
>     finally: sys.stdout = save
>
> to the simpler:
>
> def foobarRedirect(fileob, *args):
>     return foobar(*args, blotch=fileob)
>
> However, function foobar itself was cluttered by a more
> substantial amount than the wrapper was simplified, what with
> each 'print x' becoming 'print>>blotch,x' (plus the extra
> blotch=None argument to both foobar and the other function,
> also exposed from the module, that foobar calls).

As above, I don't believe I would use print>> here either.

> This has as little 'scientific' value as any other similar
> experiment, of course (which is part of why I find your
> 'more-impressed' somewhat unlikely) -- it's not a controlled
> ergonomics experiment:

We have no funding for that, so anecdotal evidence-- in the absence of a
killer argument --is the best we're going to get.

> in the end, the evaluation of "how readable and maintainable is
> the resulting code" is about as subjective and aesthetic as one's
> original appreciation of the construct.  But then, actual human-
> factors controlled experiments are just as scarce on the side
> _supporting_ 'print>>', aren't they?

There are none in either direction that I know of, and I doubt there ever
will be.  The realm of the subjective is where a BDFL is *most* needed!

> I don't think I posted on the similar experience I did with
> code previously using flob.write, but it was even worse from
> my point of view.  Changing the calls, typically originally
> all in the form:
>     flob.write(format % (a,b,c))
> to print-with-redirect:
>     print >> flob, format % (a,b,c),
> not only had no observable benefit, but actually gave a
> slight problem in a case where an unwanted blank space got
> inserted by two back-to-back 'print>>' (while the .write
> calls, of course, did not insert it).

The space-inserting gimmicks of plain "print" are best for output intended
to be read by humans, and I think that's just as true of "print>>".  I
*suspect* (but don't know) that one reason Guido found print>> attractive is
the number of msgs (over the years) directed to sys.stderr that are
*missing* crucial spaces when done in the sys.stderr.write(msg) form -- and
since they're "error msgs", sometimes years go by before we see that one of
those is damaged.

Now a space-eager printing gimmick could have been done via a function too,
but Python already *had* a stmt for that purpose.  From that POV, it was
natural to extend it.

> But then, I had even lower expectations this time -- it seems
> that 'print>>' is studied to substitute for print-plus-
> sys.stdout-changes, not for .write (which is what I most often
> use for output).

I don't think print>> is ever a good substitute for .write(), except in
those cases where .write() is being used for human-readable output and the
author didn't want to do the stdout redirection dance around plain "print".
Else automagical space-insertion gets in the way more than it helps.  Don't
know whether Guido would agree, but that's my take on it.

> The "lower expectations" may be important -- but I can't
> brainwash myself (and wouldn't if I could) to expect the
> sky and stars from a construct that strikes me so badly:
> giving it "a fair chance" may thus be impossible for me.

Try thinking of it as a minor convenience?  I do!  I could live without it;
I'd rather not.

> Still, we're all humans (or bots), and thus, this is no
> doubt a widespread issue.  I've spent an hour or so on it,
> confirmed the preconceived ideas I had before I did, and
> my opinions about 'print>>' are, as could be expected,
>
> Be that as it may, I'm still waiting to see real-life
> examples, in my code *or others'*, where the use of
> 'print>>' will strike me as "ah yes, clearly the one
> right, obvious way to do it".

A quick regexp search turns up about 135 uses in the current CVS tree.  Some
I don't like.  Some I do.  I'll mention two of the latter because I expect
to hear about all the others from you <wink>.

1. The last line of Lib/test/test_largefile.py:

    print >>sys.stderr, name, "exists:", os.path.exists(name)

A human-readable msg and the only use of sys.stderr in the module.  There is
no (IMO) alternative as obvious or convenient as this way of writing it.

2. Lib/warnings.py:  3 instances in 280 lines of code, again all trying to
write something human-readable to sys.stderr.

And I'll toss in one marginal one:  Lib/smtpd.py has 12 instances of

    print >> DEBUGSTREAM, some, human, readable, msg

That's in over 531 lines of code, and it never appears often in a single
function, so it's not being overused by my lights.  But I prefer using a
debug *function* for this kind of thing:  it's more flexible.  For example,
the module's default value for DEBUGSTREAM is

DEBUGSTREAM = Devnull()

where the author wrote a Devnull class with a do-nothing .write() method:

class Devnull:
    def write(self, msg): pass
    def flush(self): pass

While just a few lines of code, it's on the edge of being strained.  I'd
also rather see these lines as

    DEBUG(some, human, readable, msg)

because it's the DEBUG part that's important, not the "print" part (and,
indeed, the *normal* use of these lines is *not* to print!).

Ack -- it's after 4AM again, and we've got a release to get out tomorrow
(today?  who can tell anymore <wink/sigh>).  One quickie:

> ...
> I guess, when he comes around to it, since he has no C background
> to understand the rules for the format string; I'd better write up
> something for him -- or can somebody help with an URL about %-
> formatting already written up for somebody with zero C background?).

I don't, but there's a very *good* writeup at:

    http://www-ccs.ucsd.edu/c/lib_prin.html

Lots of examples, explanation, and even a railroad diagram for the syntax of
a format code (which I'm afraid is more confusing than helpful!).

At least the docs for 2.1 contain *a* description of each format code.  The
contributed patch Fred started from can be found here:

http://sourceforge.net/patch/index.php?func=detailpatch&
    patch_id=103412&group_id=5470

good-topic-for-a-"howto"!-dense-little-languages-aren't-obvious-ly
    y'rs  - tim





More information about the Python-list mailing list