<br><br><div><span class="gmail_quote">On 11/20/06, <b class="gmail_sendername">Barry Warsaw</b> &lt;<a href="mailto:barry@python.org">barry@python.org</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
-----BEGIN PGP SIGNED MESSAGE-----<br>Hash: SHA1<br><br>On Nov 20, 2006, at 1:21 PM, Guido van Rossum wrote:<br><br>&gt; On 11/20/06, Barry Warsaw &lt;<a href="mailto:barry@python.org">barry@python.org</a>&gt; wrote:<br>&gt;&gt; I'd like to at least see a discussion of a more printf() or logging
<br>&gt;&gt; style for print function.<br>&gt;<br>&gt; Agreed, as long as it isn't presented as an alternative to the more<br>&gt; basic print() function. We don't want to force students making their<br>&gt; first forays into programming to have to learn format strings. Having
<br>&gt; printf() for more advanced use together with print() as defined in PEP<br>&gt; 3105 makes sense to me.<br><br>That seems reasonable to me too (separate print() and printf()<br>thingies).<br><br>&gt;&gt; Specifically, I wonder if it wouldn't be
<br>&gt;&gt; useful to require a format string with positional and keyword<br>&gt;&gt; arguments being used for automatic interpolation.&nbsp;&nbsp;E.g.<br>&gt;&gt;<br>&gt;&gt; print('%s: %s', field, value)<br>&gt;&gt;<br>&gt;&gt; instead of
<br>&gt;&gt;<br>&gt;&gt; print('%s: %s' % (field, value))<br>&gt;<br>&gt; Before going too far down this route, first read PEP 3101, which<br>&gt; proposes a different way out of the issues around the % operator. (Not<br>
&gt; saying we couldn't adopt PEP 3101 *and* a printf() function.<br><br>Thanks for the pointer.&nbsp;&nbsp;I agree that if we adopt a companion printf<br>() function it should definitely require (only) PEP 3101 format strings.<br>
<br>&gt;&gt; Another thought: what if 'print' weren't a function but a callable<br>&gt;&gt; object. exposed in builtins.&nbsp;&nbsp;I'm thinking something roughly parallel<br>&gt;&gt; to stdout, stderr, stdin, or maybe better cout, cerr, cin.
<br>&gt;<br>&gt; I'm not sure I follow the difference. It was quite clear from earlier<br>&gt; discussions that we *don't* want print to be a bound method of a<br>&gt; hypothetical print method on sys.stdout; that's much less flexible,
<br>&gt; and makes it much more work to implement a file-like type. print()<br>&gt; should dynamically look up sys.stdout each time it is called (and<br>&gt; exactly once per call).<br>&gt;<br>&gt; (BTW I'm not sure why you like cin/cout/cerr better than stdin/
<br>&gt; stdout/stderr?)<br><br>I was trying to make an analogy (probably poorly so) that 'print'<br>would be bound to an instance as opposed to a function (current<br>proposal) or structure-like thingie without methods as in std*.
<br><br>&gt;&gt; The default 'print' object then would be a &quot;print-to-sys.stdout-with-<br>&gt;&gt; \n&quot;, but you would then be able to do something like:<br>&gt;&gt;<br>&gt;&gt; stderr = print.clone(stream=sys.stderr
)<br>&gt;&gt; stderr('here go all my error messages')<br>&gt;&gt;<br>&gt;&gt; or<br>&gt;&gt;<br>&gt;&gt; smtpout = print.clone(stream=mysock, end='\r\n')<br>&gt;&gt; smtpout('$code $msg', code=250, msg='Okay')<br>&gt;<br>
&gt; I'd like to firmly resist adding more mechanism for somethign that can<br>&gt; be addressed so simply by a tiny wrapper function:<br>&gt;<br>&gt; def smtpout(*args):<br>&gt;&nbsp;&nbsp;print(*args, file=mysock, end=&quot;\r\n&quot;)
<br><br>What I was trying to address was the namespace collisions you'd get<br>between printf-style keyword arguments and 'special' arguments that<br>the print function would accept.&nbsp;&nbsp;The thing is that if we were to add<br>
both a print and a printf, you'd like for their interfaces to be as<br>similar as possible except that the latter takes a format string as<br>its first argument.&nbsp;&nbsp;Clearly 'special' arguments like 'file' and<br>'end' will prohibit their use as keyword arguments for printf, and I
<br>don't like that (this isn't anything new -- the problem crops up<br>occasionally in other places, see the email package API).</blockquote><div><br>Why do they need to be similar?&nbsp; print() is just a really simple, quick output function.&nbsp; printf() seems to be proposed for advanced formatting needs for sending to stdout.&nbsp; As Guido said, the newline should be explicit in printf(), so that already begins to deviate from print().&nbsp; And 'sep' would be useless.&nbsp; So all that leaves is 'file', and that is just convenience for passing a string to a 'write' method.&nbsp; And for that I think people can just learn not to use 'file' as a name of a variable.&nbsp; Or we can just lose that as well and have printf() be nothing more than a convenience function that avoids having to specify the method name and sending it to print with the desired arguments.
<br><br>Then again, this to me seems to make printf() not that grand to lead to its own built-in.&nbsp; But I have been fine with the way things have been so far anyway with having a separate line that stores some string I created before calling 'print'.&nbsp; If you don't have any keyword arguments then printf() is just::
<br><br>&nbsp; def printf(format_string, *args, **kwargs):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output = format_string.format(*args, **kwargs)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(output, end='')<br><br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
One way out would be to use special argument names, e.g. prepending<br>and or appending some number of underscores.&nbsp;&nbsp;This doesn't eliminate<br>the problem, but it reduces its likelihood.</blockquote><div><br>I don't see this being a big problem if the only argument that is common is 'file'.
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">&nbsp;&nbsp;Another approach would<br>for 'print' to be an object with attributes that would change
<br>behavior, such as the stream to write to or line-ending characters.</blockquote><div><br>Yuck.&nbsp; Why would you want to suddenly set global semantics in a built-in instead of a module?&nbsp; That's a total shift in how Python does things at a global level.&nbsp; Plus I don't want to have to worry about setting 'sep' or 'end' for every function that uses print() just because some other function decided that it didn't like single spaces but wanted to use tabs for a separator.
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">A possible third approach might be some special singleton objects<br>that, when seen positionally would modify the state of the underlying
<br>print object.</blockquote><div><br>Yuck again. This seems to be getting rather specific just for printing when we have already lived without all of this functionality for so long with minor issue.<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
&nbsp;&nbsp;Of the three (maybe fourth: &quot;sorry you can't use 'end'<br>or 'file'&quot;),</blockquote><div><br>I like this option.&nbsp; =) <br></div><br>-Brett<br></div>