mirror of
https://github.com/kennethreitz/dive-into-python3.git
synced 2026-06-05 23:10:17 +00:00
389 lines
28 KiB
HTML
389 lines
28 KiB
HTML
<!DOCTYPE html>
|
|
<head>
|
|
<meta charset=utf-8>
|
|
<title>Files - Dive into Python 3</title>
|
|
<!--[if IE]><script src=j/html5.js></script><![endif]-->
|
|
<link rel=stylesheet href=dip3.css>
|
|
<style>
|
|
body{counter-reset:h1 12}
|
|
</style>
|
|
<link rel=stylesheet type=text/css media='only screen and (max-device-width: 480px)' href=mobile.css>
|
|
<link rel=stylesheet media=print href=print.css>
|
|
<meta name=viewport content='initial-scale=1.0'>
|
|
</head>
|
|
<form action=http://www.google.com/cse><div><input type=hidden name=cx value=014021643941856155761:l5eihuescdw><input type=hidden name=ie value=UTF-8> <input name=q size=25> <input type=submit name=sa value=Search></div></form>
|
|
<p>You are here: <a href=index.html>Home</a> <span class=u>‣</span> <a href=table-of-contents.html#files>Dive Into Python 3</a> <span class=u>‣</span>
|
|
<p id=level>Difficulty level: <span class=u title=intermediate>♦♦♦♢♢</span>
|
|
<h1>Files</h1>
|
|
<blockquote class=q>
|
|
<p><span class=u>❝</span> FIXME <span class=u>❞</span><br>— FIXME
|
|
</blockquote>
|
|
<p id=toc>
|
|
<h2 id=divingin>Diving In</h2>
|
|
<p class=f>FIXME
|
|
|
|
<!--
|
|
FIXME move this to character encoding section
|
|
|
|
OK, so a string is a sequence of Unicode characters. But a file on disk is not a sequence of Unicode characters; a file on disk is a sequence of bytes. So if you read a “text file” from disk, how does Python convert that sequence of bytes into a sequence of characters? The answer is that it decodes the bytes according to a specific character encoding algorithm, and returns a sequence of Unicode characters, otherwise known as a string.
|
|
|
|
"The default encoding is platform dependent (whatever locale.getpreferredencoding() returns)." -- http://docs.python.org/3.1/library/io.html
|
|
-->
|
|
|
|
<h2 id=reading-from-text-files>Reading From Text Files</h2>
|
|
|
|
<p>FIXME
|
|
|
|
<pre>
|
|
open(..., encoding='...')
|
|
open(..., 'r', encoding='...')
|
|
</pre>
|
|
|
|
<h3 id=encoding>Character Encoding Rears Its Ugly Head</h3>
|
|
|
|
<p>FIXME
|
|
|
|
<h3 id=file-objects>File Objects</h3>
|
|
|
|
<p>FIXME
|
|
|
|
<p>Python has a built-in function, <code>open()</code>, for opening a file on disk. The <code>open()</code> function returns a <i>file object</i>, which has methods and attributes for getting information about and manipulating the file.
|
|
|
|
<!--
|
|
<ol>
|
|
<li>The <code>open</code> method can take up to three parameters: a filename, a mode, and a buffering parameter. Only the first one, the filename, is required; the other two are <a href="#apihelper.optional" title="4.2. Using Optional and Named Arguments">optional</a>. If not specified, the file is opened for reading in text mode. Here you are opening the file for reading in binary mode. (<code>print open.__doc__</code> displays a great explanation of all the possible modes.)
|
|
<li>The <code>open</code> function returns an object (by now, <a href="#odbchelper.objects" title="2.4. Everything Is an Object">this should not surprise you</a>). A file object has several useful attributes.
|
|
<li>The <var>mode</var> attribute of a file object tells you in which mode the file was opened.
|
|
<li>The <var>name</var> attribute of a file object tells you the name of the file that the file object has open.
|
|
-->
|
|
|
|
<h3 id=read>Reading Data From A Text File</h3>
|
|
|
|
<p>FIXME
|
|
|
|
<!--
|
|
<p>After you open a file, the first thing you’ll want to do is read from it, as shown in the next example.
|
|
<div class=example><h3>Example 6.4. Reading a File</h3><pre class=screen>
|
|
<samp class=p>>>> </samp><kbd>f</kbd>
|
|
<open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
|
|
<samp class=p>>>> </samp><kbd>f.tell()</kbd> <span>①</span>
|
|
0
|
|
<samp class=p>>>> </samp><kbd>f.seek(-128, 2)</kbd> <span>②</span>
|
|
<samp class=p>>>> </samp><kbd>f.tell()</kbd> <span>③</span>
|
|
7542909
|
|
<samp class=p>>>> </samp><kbd>tagData = f.read(128)</kbd> <span>④</span>
|
|
<samp class=p>>>> </samp><kbd>tagData</kbd>
|
|
<samp>'TAGKAIRO****THE BEST GOA ***DJ MARY-JANE***
|
|
Rave Mix 2000http://mp3.com/DJMARYJANE \037'</samp>
|
|
<samp class=p>>>> </samp><kbd>f.tell()</kbd> <span>⑤</span>
|
|
7543037</pre>
|
|
<ol>
|
|
<li>A file object maintains state about the file it has open. The <code>tell</code> method of a file object tells you your current position in the open file. Since you haven’t done anything with this file yet, the current position is <code>0</code>, which is the beginning of the file.
|
|
<li>The <code>seek</code> method of a file object moves to another position in the open file. The second parameter specifies what the first one means;
|
|
<code>0</code> means move to an absolute position (counting from the start of the file), <code>1</code> means move to a relative position (counting from the current position), and <code>2</code> means move to a position relative to the end of the file. Since the <abbr>MP3</abbr> tags you’re looking for are stored at the end of the file, you use <code>2</code> and tell the file object to move to a position <code>128</code> bytes from the end of the file.
|
|
<li>The <code>tell</code> method confirms that the current file position has moved.
|
|
<li>The <code>read</code> method reads a specified number of bytes from the open file and returns a string with the data that was read. The optional parameter specifies the maximum number of bytes to read. If no parameter is specified, <code>read</code> will read until the end of the file. (You could have simply said <code>read()</code> here, since you know exactly where you are in the file and you are, in fact, reading the last 128 bytes.) The read data is assigned to the <var>tagData</var> variable, and the current position is updated based on how many bytes were read.
|
|
<li>The <code>tell</code> method confirms that the current position has moved. If you do the math, you’ll see that after reading 128 bytes, the position has been incremented by 128.
|
|
-->
|
|
|
|
<h3>6.2.2. Closing Files</h3>
|
|
|
|
<p>Open files consume system resources, and depending on the file mode, other programs may not be able to access them. It’s important to close files as soon as you’re finished with them.
|
|
|
|
<!--
|
|
<div class=example><h3>Example 6.5. Closing a File</h3><pre class=screen>
|
|
<samp class=p>>>> </samp><kbd>f</kbd>
|
|
<open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
|
|
<samp class=p>>>> </samp><kbd>f.closed</kbd> <span>①</span>
|
|
False
|
|
<samp class=p>>>> </samp><kbd>f.close()</kbd> <span>②</span>
|
|
<samp class=p>>>> </samp><kbd>f</kbd>
|
|
<closed file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
|
|
<samp class=p>>>> </samp><kbd>f.closed</kbd> <span>③</span>
|
|
True
|
|
<samp class=p>>>> </samp><kbd>f.seek(0)</kbd> <span>④</span>
|
|
<samp class=traceback>Traceback (innermost last):
|
|
File "<interactive input>", line 1, in ?
|
|
ValueError: I/O operation on closed file</samp>
|
|
<samp class=p>>>> </samp><kbd>f.tell()</kbd>
|
|
<samp class=traceback>Traceback (innermost last):
|
|
File "<interactive input>", line 1, in ?
|
|
ValueError: I/O operation on closed file</samp>
|
|
<samp class=p>>>> </samp><kbd>f.read()</kbd>
|
|
<samp class=traceback>Traceback (innermost last):
|
|
File "<interactive input>", line 1, in ?
|
|
ValueError: I/O operation on closed file</samp>
|
|
<samp class=p>>>> </samp><kbd>f.close()</kbd> <span>⑤</span></pre>
|
|
<ol>
|
|
<li>The <var>closed</var> attribute of a file object indicates whether the object has a file open or not. In this case, the file is still open (<var>closed</var> is <code>False</code>).
|
|
<li>To close a file, call the <code>close</code> method of the file object. This frees the lock (if any) that you were holding on the file, flushes buffered writes (if any) that the system hadn’t gotten around to actually writing yet, and releases the system resources.
|
|
<li>The <var>closed</var> attribute confirms that the file is closed.
|
|
<li>Just because a file is closed doesn’t mean that the file object ceases to exist. The variable <var>f</var> will continue to exist until it <a href="#fileinfo.scope" title="Example 5.8. Trying to Implement a Memory Leak">goes out of scope</a> or gets manually deleted. However, none of the methods that manipulate an open file will work once the file has been closed; they all raise an exception.
|
|
<li>Calling <code>close</code> on a file object whose file is already closed does <em>not</em> raise an exception; it fails silently.
|
|
-->
|
|
|
|
<p>FIXME checking if a file is closed
|
|
|
|
<h3 id=with>Using The <code>with</code> Statement</h3>
|
|
|
|
<p>FIXME "with open(...) as file" pattern
|
|
|
|
<h3 id=one-line-at-a-time>Reading Data One Line At A Time</h3>
|
|
|
|
<p>FIXME
|
|
|
|
<p>FIXME what's a "line"? (line endings discussion, universal line endings, etc.)
|
|
|
|
<h2 id=write>Writing to Text Files</h2>
|
|
|
|
<p>FIXME
|
|
|
|
<!--
|
|
<p>As you would expect, you can also write to files in much the same way that you read from them. There are two basic file modes:
|
|
<div class=itemizedlist>
|
|
<ul>
|
|
<li>"Append" mode will add data to the end of the file.
|
|
<li>"write" mode will overwrite the file.
|
|
</ul>
|
|
<p>Either mode will create the file automatically if it doesn’t already exist, so there’s never a need for any sort of fiddly
|
|
"if the log file doesn't exist yet, create a new empty file just so you can open it for the first time" logic. Just open
|
|
it and start writing.
|
|
<div class=example><h3 id="fileinfo.files.writeandappend">Example 6.7. Writing to Files</h3><pre class=screen>
|
|
<samp class=p>>>> </samp><kbd>logfile = open('test.log', 'w')</kbd> <span>①</span>
|
|
<samp class=p>>>> </samp><kbd>logfile.write('test succeeded')</kbd> <span>②</span>
|
|
<samp class=p>>>> </samp><kbd>logfile.close()</kbd>
|
|
<samp class=p>>>> </samp><kbd>print file('test.log').read()</kbd> <span>③</span>
|
|
test succeeded
|
|
<samp class=p>>>> </samp><kbd>logfile = open('test.log', 'a')</kbd> <span>④</span>
|
|
<samp class=p>>>> </samp><kbd>logfile.write('line 2')</kbd>
|
|
<samp class=p>>>> </samp><kbd>logfile.close()</kbd>
|
|
<samp class=p>>>> </samp><kbd>print file('test.log').read()</kbd> <span>⑤</span>
|
|
test succeededline 2
|
|
</pre>
|
|
<ol>
|
|
<li>You start boldly by creating either the new file <code>test.log</code> or overwrites the existing file, and opening the file for writing. (The second parameter <code>"w"</code> means open the file for writing.) Yes, that’s all as dangerous as it sounds. I hope you didn’t care about the previous contents of that file, because it’s gone now.
|
|
<li>You can add data to the newly opened file with the <code>write</code> method of the file object returned by <code>open</code>.
|
|
<li><code>file</code> is a synonym for <code>open</code>. This one-liner opens the file, reads its contents, and prints them.
|
|
<li>You happen to know that <code>test.log</code> exists (since you just finished writing to it), so you can open it and append to it. (The <code>"a"</code> parameter means open the file for appending.) Actually you could do this even if the file didn’t exist, because opening the file for appending will create the file if necessary. But appending will <em>never</em> harm the existing contents of the file.
|
|
<li>As you can see, both the original line you wrote and the second line you appended are now in <code>test.log</code>. Also note that carriage returns are not included. Since you didn’t write them explicitly to the file either time, the file doesn’t include them. You can write a carriage return with the <code>"\n"</code> character. Since you didn’t do this, everything you wrote to the file ended up smooshed together on the same line.
|
|
-->
|
|
|
|
<h3 id=encoding-again>Character Encoding Again</h3>
|
|
|
|
<p>FIXME
|
|
|
|
<h3 id=write-methods>Write A Little, Write A Lot</h3>
|
|
|
|
<p>FIXME write(), writelines(), .writeable
|
|
|
|
<h2 id=ioerror>Handling I/O Errors</h2>
|
|
|
|
<p>FIXME
|
|
|
|
<!--
|
|
<p>Now you’ve seen enough to understand the file handling code in the <code>fileinfo.py</code> sample code from the previous chapter. This example shows how to safely open and read from a file and gracefully handle
|
|
errors.
|
|
<div class=example><h3 id="fileinfo.files.incode">Example 6.6. File Objects in <code>MP3FileInfo</code></h3><pre><code>
|
|
try: <span>①</span> fsock = open(filename, "rb", 0) <span>②</span> try: fsock.seek(-128, 2) <span>③</span> tagdata = fsock.read(128) <span>④</span> finally: <span>⑤</span> fsock.close() . . .
|
|
except IOError: <span>⑥</span> pass </pre>
|
|
<ol>
|
|
<li>Because opening and reading files is risky and may raise an exception, all of this code is wrapped in a <code>try...except</code> block. (Hey, isn’t <a href="#odbchelper.indenting" title="2.5. Indenting Code">standardized indentation</a> great? This is where you start to appreciate it.)
|
|
<li>The <code>open</code> function may raise an <code>IOError</code>. (Maybe the file doesn’t exist.)
|
|
<li>The <code>seek</code> method may raise an <code>IOError</code>. (Maybe the file is smaller than 128 bytes.)
|
|
<li>The <code>read</code> method may raise an <code>IOError</code>. (Maybe the disk has a bad sector, or it’s on a network drive and the network just went down.)
|
|
<li>This is new: a <code>try...finally</code> block. Once the file has been opened successfully by the <code>open</code> function, you want to make absolutely sure that you close it, even if an exception is raised by the <code>seek</code> or <code>read</code> methods. That’s what a <code>try...finally</code> block is for: code in the <code>finally</code> block will <em>always</em> be executed, even if something in the <code>try</code> block raises an exception. Think of it as code that gets executed on the way out, regardless of what happened before.
|
|
<li>At last, you handle your <code>IOError</code> exception. This could be the <code>IOError</code> exception raised by the call to <code>open</code>, <code>seek</code>, or <code>read</code>. Here, you really don’t care, because all you’re going to do is ignore it silently and continue. (Remember, <code>pass</code> is a Python statement that <a href="#fileinfo.class.simplest" title="Example 5.3. The Simplest Python Class">does nothing</a>.) That’s perfectly legal; “handling” an exception can mean explicitly doing nothing. It still counts as handled, and processing will continue normally on the next line of code after the <code>try...except</code> block.
|
|
-->
|
|
|
|
<h2 id=binary-files>Binary Files</h2>
|
|
|
|
<p>FIXME
|
|
|
|
<pre>
|
|
>>> image = open('examples/beauregard-100x100.jpg', 'rb')
|
|
>>> image
|
|
<io.BufferedReader object at 0x00C7A390>
|
|
>>> image.mode
|
|
'rb'
|
|
>>> image.name
|
|
'examples/beauregard-100x100.jpg'
|
|
</pre>
|
|
|
|
<pre>
|
|
>>> image
|
|
<io.BufferedReader object at 0x00C7A390>
|
|
>>> image.tell()
|
|
0
|
|
>>> data = image.read(3)
|
|
>>> data
|
|
b'\xff\xd8\xff'
|
|
>>> image.tell()
|
|
3
|
|
>>> image.seek(0)
|
|
0
|
|
>>> data = image.read()
|
|
>>> len(data)
|
|
3150
|
|
</pre>
|
|
|
|
<h2 id=file-like-objects>File-like Objects</h2>
|
|
|
|
<p>FIXME
|
|
|
|
<!--
|
|
<p>One of Python’s greatest strengths is its dynamic binding, and one powerful use of dynamic binding is the <dfn>file-like object</dfn>.
|
|
|
|
<p>Many functions which require an input source could simply take a filename, go open the file for reading, read it, and close it when they’re done. But they don’t. Instead, they take a <em>file-like object</em>.
|
|
|
|
<p>In the simplest case, a <em>file-like object</em> is any object with a <code>read</code> method with an optional <var>size</var> parameter, which returns a string. When called with no <var>size</var> parameter, it reads everything there is to read from the input source and returns all the data as a single string. When
|
|
called with a <var>size</var> parameter, it reads that much from the input source and returns that much data; when called again, it picks up where it left
|
|
off and returns the next chunk of data.
|
|
<p>This is how <a href="#fileinfo.files" title="6.2. Working with File Objects">reading from real files</a> works; the difference is that you’re not limiting yourself to real files. The input source could be anything: a file on
|
|
disk, a web page, even a hard-coded string. As long as you pass a file-like object to the function, and the function simply
|
|
calls the object’s <code>read</code> method, the function can handle any kind of input source without specific code to handle each kind.
|
|
-->
|
|
|
|
<!--
|
|
<div class=example><h3 id="kgp.openanything.stringio.example">Example 10.4. Introducing <code>StringIO</code></h3><pre class=screen>
|
|
<samp class=p>>>> </samp><kbd>contents = "<grammar><ref id='bit'><p>0</p><p>1</p></ref></grammar>"</kbd>
|
|
<samp class=p>>>> </samp><kbd>import StringIO</kbd>
|
|
<samp class=p>>>> </samp><kbd>ssock = StringIO.StringIO(contents)</kbd> <span>①</span>
|
|
<samp class=p>>>> </samp><kbd>ssock.read()</kbd> <span>②</span>
|
|
"<grammar><ref id='bit'><p>0</p><p>1</p></ref></grammar>"
|
|
<samp class=p>>>> </samp><kbd>ssock.read()</kbd> <span>③</span>
|
|
''
|
|
<samp class=p>>>> </samp><kbd>ssock.seek(0)</kbd> <span>④</span>
|
|
<samp class=p>>>> </samp><kbd>ssock.read(15)</kbd> <span>⑤</span>
|
|
'<grammar><ref i'
|
|
<samp class=p>>>> </samp><kbd>ssock.read(15)</kbd>
|
|
"d='bit'><p>0</p"
|
|
<samp class=p>>>> </samp><kbd>ssock.read()</kbd>
|
|
'><p>1</p></ref></grammar>'
|
|
<samp class=p>>>> </samp><kbd>ssock.close()</kbd> <span>⑥</span></pre>
|
|
<ol>
|
|
<li>The <code>StringIO</code> module contains a single class, also called <code>StringIO</code>, which allows you to turn a string into a file-like object. The <code>StringIO</code> class takes the string as a parameter when creating an instance.
|
|
<li>Now you have a file-like object, and you can do all sorts of file-like things with it. Like <code>read</code>, which returns the original string.
|
|
<li>Calling <code>read</code> again returns an empty string. This is how real file objects work too; once you read the entire file, you can’t read any more without explicitly seeking to the beginning of the file. The <code>StringIO</code> object works the same way.
|
|
<li>You can explicitly seek to the beginning of the string, just like seeking through a file, by using the <code>seek</code> method of the <code>StringIO</code> object.
|
|
<li>You can also read the string in chunks, by passing a <var>size</var> parameter to the <code>read</code> method.
|
|
<li>At any time, <code>read</code> will return the rest of the string that you haven’t read yet. All of this is exactly how file objects work; hence the term
|
|
<em>file-like object</em>.
|
|
-->
|
|
|
|
<h2 id=stdio>Standard Input, Output, and Error</h2>
|
|
|
|
<p>FIXME
|
|
|
|
<!--
|
|
<p><abbr>UNIX</abbr> users are already familiar with the concept of standard input, standard output, and standard error. This section is for
|
|
the rest of you.
|
|
<p>Standard output and standard error (commonly abbreviated <code>stdout</code> and <code>stderr</code>) are pipes that are built into every <abbr>UNIX</abbr> system. When you <code>print</code> something, it goes to the <code>stdout</code> pipe; when your program crashes and prints out debugging information (like a traceback in Python), it goes to the <code>stderr</code> pipe. Both of these pipes are ordinarily just connected to the terminal window where you are working, so when a program
|
|
prints, you see the output, and when a program crashes, you see the debugging information. (If you’re working on a system
|
|
with a window-based Python <abbr>IDE</abbr>, <code>stdout</code> and <code>stderr</code> default to your “Interactive Window”.)
|
|
<div class=example><h3>Example 10.8. Introducing <code>stdout</code> and <code>stderr</code></h3><pre class=screen>
|
|
<samp class=p>>>> </samp><kbd>for i in range(3):</kbd>
|
|
<samp class=p>... </samp>print 'Dive in' <span>①</span>
|
|
<samp>Dive in
|
|
Dive in
|
|
Dive in</samp>
|
|
<samp class=p>>>> </samp><kbd>import sys</kbd>
|
|
<samp class=p>>>> </samp><kbd>for i in range(3):</kbd>
|
|
<samp class=p>... </samp>sys.stdout.write('Dive in') <span>②</span>
|
|
Dive inDive inDive in
|
|
<samp class=p>>>> </samp><kbd>for i in range(3):</kbd>
|
|
<samp class=p>... </samp>sys.stderr.write('Dive in') <span>③</span>
|
|
Dive inDive inDive in</pre>
|
|
<ol>
|
|
<li>As you saw in <a href="#fileinfo.for.counter" title="Example 6.9. Simple Counters">Example 6.9, “Simple Counters”</a>, you can use Python’s built-in <code>range</code> function to build simple counter loops that repeat something a set number of times.
|
|
<li><code>stdout</code> is a file-like object; calling its <code>write</code> function will print out whatever string you give it. In fact, this is what the <code>print</code> function really does; it adds a carriage return to the end of the string you’re printing, and calls <code>sys.stdout.write</code>.
|
|
<li>In the simplest case, <code>stdout</code> and <code>stderr</code> send their output to the same place: the Python <abbr>IDE</abbr> (if you’re in one), or the terminal (if you’re running Python from the command line). Like <code>stdout</code>, <code>stderr</code> does not add carriage returns for you; if you want them, add them yourself.
|
|
<p><code>stdout</code> and <code>stderr</code> are both file-like objects, like the ones you discussed in <a href="#kgp.openanything" title="10.1. Abstracting input sources">Section 10.1, “Abstracting input sources”</a>, but they are both write-only. They have no <code>read</code> method, only <code>write</code>. Still, they are file-like objects, and you can assign any other file- or file-like object to them to redirect their output.
|
|
<div class=example><h3>Example 10.9. Redirecting output</h3><pre class=screen>
|
|
<samp class=p>[you@localhost kgp]$ </samp>python stdout.py
|
|
Dive in
|
|
<samp class=p>[you@localhost kgp]$ </samp>cat out.log
|
|
This message will be logged instead of displayed</pre><p>(On Windows, you can use <code>type</code> instead of <code>cat</code> to display the contents of a file.)
|
|
<p>If you have not already done so, you can <a href="http://diveintopython3.org/download/diveintopython3-examples-5.4.zip" title="Download example scripts">download this and other examples</a> used in this book.
|
|
<pre><code>
|
|
#stdout.py
|
|
import sys
|
|
|
|
print 'Dive in' <span>①</span>
|
|
saveout = sys.stdout <span>②</span>
|
|
fsock = open('out.log', 'w') <span>③</span>
|
|
sys.stdout = fsock <span>④</span>
|
|
print 'This message will be logged instead of displayed' <span>⑤</span>
|
|
sys.stdout = saveout <span>⑥</span>
|
|
fsock.close() <span>⑦</span>
|
|
</pre>
|
|
<ol>
|
|
<li>This will print to the <abbr>IDE</abbr> “Interactive Window” (or the terminal, if running the script from the command line).
|
|
<li>Always save <code>stdout</code> before redirecting it, so you can set it back to normal later.
|
|
<li>Open a file for writing. If the file doesn’t exist, it will be created. If the file does exist, it will be overwritten.
|
|
<li>Redirect all further output to the new file you just opened.
|
|
<li>This will be “printed” to the log file only; it will not be visible in the <abbr>IDE</abbr> window or on the screen.
|
|
<li>Set <code>stdout</code> back to the way it was before you mucked with it.
|
|
<li>Close the log file.
|
|
<p>Redirecting <code>stderr</code> works exactly the same way, using <code>sys.stderr</code> instead of <code>sys.stdout</code>.
|
|
<div class=example><h3>Example 10.10. Redirecting error information</h3><pre class=screen>
|
|
<samp class=p>[you@localhost kgp]$ </samp>python stderr.py
|
|
<samp class=p>[you@localhost kgp]$ </samp>cat error.log
|
|
<samp>Traceback (most recent line last):
|
|
File "stderr.py", line 5, in ?
|
|
raise Exception, 'this error will be logged'
|
|
Exception: this error will be logged</span></pre><p>If you have not already done so, you can <a href="http://diveintopython3.org/download/diveintopython3-examples-5.4.zip" title="Download example scripts">download this and other examples</a> used in this book.
|
|
<pre><code>
|
|
#stderr.py
|
|
import sys
|
|
|
|
fsock = open('error.log', 'w') <span>①</span>
|
|
sys.stderr = fsock <span>②</span>
|
|
raise Exception, 'this error will be logged' <span>③</span> <span>④</span>
|
|
</pre>
|
|
<ol>
|
|
<li>Open the log file where you want to store debugging information.
|
|
<li>Redirect standard error by assigning the file object of the newly-opened log file to <code>stderr</code>.
|
|
<li>Raise an exception. Note from the screen output that this does <em>not</em> print anything on screen. All the normal traceback information has been written to <code>error.log</code>.
|
|
<li>Also note that you’re not explicitly closing your log file, nor are you setting <code>stderr</code> back to its original value. This is fine, since once the program crashes (because of the exception), Python will clean up and close the file for us, and it doesn’t make any difference that <code>stderr</code> is never restored, since, as I mentioned, the program crashes and Python ends. Restoring the original is more important for <code>stdout</code>, if you expect to go do other stuff within the same script afterwards.
|
|
<p>Since it is so common to write error messages to standard error, there is a shorthand syntax that can be used instead of going
|
|
through the hassle of redirecting it outright.
|
|
<div class=example><h3 id="kgp.stdio.print.example">Example 10.11. Printing to <code>stderr</code></h3><pre class=screen>
|
|
<samp class=p>>>> </samp><kbd>print 'entering function'</kbd>
|
|
entering function
|
|
<samp class=p>>>> </samp><kbd>import sys</kbd>
|
|
<samp class=p>>>> </samp><kbd>print >> sys.stderr, 'entering function'</kbd> <span>①</span>
|
|
entering function
|
|
</pre>
|
|
<ol>
|
|
<li>This shorthand syntax of the <code>print</code> statement can be used to write to any open file, or file-like object. In this case, you can redirect a single <code>print</code> statement to <code>stderr</code> without affecting subsequent <code>print</code> statements.
|
|
<p>Standard input, on the other hand, is a read-only file object, and it represents the data flowing into the program from some
|
|
previous program. This will likely not make much sense to classic Mac OS users, or even Windows users unless you were ever fluent on the <abbr>MS-DOS</abbr> command line. The way it works is that you can construct a chain of commands in a single line, so that one program’s output
|
|
becomes the input for the next program in the chain. The first program simply outputs to standard output (without doing any
|
|
special redirecting itself, just doing normal <code>print</code> statements or whatever), and the next program reads from standard input, and the operating system takes care of connecting
|
|
one program’s output to the next program’s input.
|
|
-->
|
|
|
|
<h2 id=further-reading>Further Reading</h2>
|
|
|
|
<p>FIXME
|
|
|
|
<!--
|
|
<ul>
|
|
<li><a href="http://www.python.org/doc/current/tut/tut.html"><i class=citetitle>Python Tutorial</i></a> discusses reading and writing files, including how to <a href="http://www.python.org/doc/current/tut/node9.html#SECTION009210000000000000000">read a file one line at a time into a list</a>.
|
|
|
|
<li><a href="http://www.effbot.org/guides/">eff-bot</a> discusses efficiency and performance of <a href="http://www.effbot.org/guides/readline-performance.htm">various ways of reading a file</a>.
|
|
|
|
<li><a href="http://www.faqts.com/knowledge-base/index.phtml/fid/199/">Python Knowledge Base</a> answers <a href="http://www.faqts.com/knowledge-base/index.phtml/fid/552">common questions about files</a>.
|
|
|
|
<li><a href="http://www.python.org/doc/current/lib/"><i class=citetitle>Python Library Reference</i></a> summarizes <a href="http://www.python.org/doc/current/lib/bltin-file-objects.html">all the file object methods</a>.
|
|
|
|
</ul>
|
|
-->
|
|
|
|
<p class=v><a href=advanced-classes.html rel=prev title='back to “Advanced Classes”'><span class=u>☜</span></a> <a href=xml.html rel=next title='onward to “XML”'><span class=u>☞</span></a>
|
|
|
|
<p class=c>© 2001–9 <a href=about.html>Mark Pilgrim</a>
|
|
<script src=j/jquery.js></script>
|
|
<script src=j/prettify.js></script>
|
|
<script src=j/dip3.js></script>
|