On Wed, May 15, 2013 at 8:07 PM, Steven D'Aprano <st...@pearwood.info> wrote:
> On 16/05/13 06:02, Alan Gauld wrote:
>>
>> And C's printf() returns the number of chars printed.
>> I actually wish python had followed suit because, as Marc says,
>> it can occasionally be useful...
>
> Guido's time machine strikes again.
>
> py> import sys
> py> sys.stdout.write('NOBODY expects the Spanish Inquisition!\n')
> NOBODY expects the Spanish Inquisition!
> 40
>
> The write() method of file objects in Python 3 return the number of
> characters written.

sys.stdout is a TextIOWrapper, so the return value is the number of
Unicode code points written. If this returns (barring exception), the
return value is guaranteed to be the length of the string; it returns
PyLong_FromSsize_t(textlen).

If you want the number of bytes written, use the underlying
BufferedWriter instead:

    >>> sys.stdout.encoding
    'UTF-8'
    >>> sys.stdout.write('\u0200\n')
    Ȁ
    2
    >>> sys.stdout.buffer.write('\u0200\n'.encode())
    Ȁ
    3

The return value is the length in bytes. Whatever isn't immediately
written to the file is saved in the buffer to be written later.

Having a return value that's less than the length is possible for
non-buffered IO (not available for text I/O). Here's an example
comparing raw vs buffered I/O after setting a file-size resource limit
of 1000 bytes:

    >>> import resource
    >>> resource.setrlimit(resource.RLIMIT_FSIZE, (1000, 1000))

An unbuffered FileIO object is immediately honest about the number of
bytes written:

    >>> f = open('temp.bin', 'wb', buffering=0)
    >>> f.write(b'spam' * 1000)
    1000
    >>> f.close()

 On the other hand a BufferedWriter will buffer the remaining 3000
bytes that can't be written. You won't find out until an exception is
raised when the file is closed:

    >>> f = open('temp.bin', 'wb')
    >>> f.write(b'spam' * 1000)
    4000
    >>> f.close()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: [Errno 27] File too large

Regarding built-in print(), you'd have to modify the underlying
PyFile_WriteObject and PyFile_WriteString functions. Currently they
throw away the return object of the file's write() method and instead
return a C int, either 0 (success) or -1 (error). But considering
print() only works with text I/O, for which the underlying write()
simply returns the string length, what's the use case?
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to