[Python-Dev] Replacement for print in Python 3.0

Nick Coghlan ncoghlan at gmail.com
Tue Sep 6 12:44:19 CEST 2005


Guido van Rossum wrote:
 > If there are other use cases they can obviously be coded by using (b)
 > and a modest amount of custom code. (I know there's the use case of
 > printing sequences; I'll try to give an analysis of this use case in
 > another post if one of its proponents doesn't do so soon.)

I did a fair bit of tinkering with that on the weekend. Printing a sequence of 
strings is fine - it's the call to "map(str, seq)" that makes printing a 
sequence of non-strings uglier than it should be. Doing it that way also 
breaks the Python idiom of letting unicode remain as unicode.

However, one thing I eventually remembered was a discussion about a year ago 
regarding the possibility of allowing str.join and unicode.join to accept 
non-strings [1].

That discussion ended up leaving the join methods alone, because it is damn 
hard to do it without slowing down the common case where the sequence is all 
strings.

I'm currently considering proposing a "joinany" method for str and unicode 
which accepts a sequence of arbitrary objects (I have a patch, but it needs 
unit tests and docs, and I'm uncomfortable with the amount of code duplication 
between the join and joinany methods).

[1] http://mail.python.org/pipermail/python-dev/2004-August/048516.html

> Some examples of the design pattern in action are str.strip(),
> str.lstrip() and str.rstrip(), or str.find() and str.rfind().
> 
> A much stronger subcase of this pattern (with fewer exceptions) is
> that the return type of a function shouldn't depend on the value of an
> argument. I have a feeling that if we were to extend the notion of
> type to include invariants, you'd find that the basic pattern is
> actually the same -- often the variant behaviors change the key
> invariant relationships between input and output.

This becomes especially clear once "sorted" and "list.sort" are given as 
examples where the various keyword arguments do not change the basic invariant 
properties of the sorting operations - you start with a sequence, and you end 
up with essentially the same sequence, only in a different order. The keyword 
arguments simply control the precise meaning of "different order".

> (a) print(...)
> (b) printraw(...) or printbare(...)
> (c) printf(fmt, ...)

Hmm, I like those names better than anything else that has come up so far.

> Each can take a keyword parameter to specify a different stream than
> sys.stdout; but no other options are needed. The names for (a) and (c)
> are pretty much fixed by convention (and by the clamoring when I
> proposed write() :-). I'm not so sure about the best name for (b), but
> I think picking the right name is important.

'printraw' is good - it makes it clear it is part of the same family as 
'print' and 'printf', and explains succintly how it differs from the normal 
print function.

> We could decide not to provide (b) directly, since it is easily
> reduced to (c) using an appropriate format string ("%s" times the
> number of arguments). But I expect that use case (b) is pretty
> important, and not everyone likes having to use format strings. This
> could be reduced to a special case of the Swiss Army Knife (...Not)
> rule.

Additionally, doing 'printraw' with 'printf' is a little tricky - the best 
I've come up with is "printf('%s'*3, a, b, c)".

> BTW we could use "from __future__ import printing" to disable the
> recognition of 'print' as a keyword in a particular module -- this
> would provide adequate future-proofing.

Gah, sometimes I miss the most obvious of solutions. . .

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.blogspot.com


More information about the Python-Dev mailing list