Skip to content

Commit 09becda

Browse files
committed
files
1 parent 3acaba3 commit 09becda

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

appendix/file_handles/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# File Handles
2+
3+
A file's name is a string like `'nobody.txt'`. To read or write the contents of the file, you need a *file handle* which you can get from `open`. Think of a file name as the address of your house. It's where your house can be found, but I can't know what's in your house unless I go there and open the door. That's what `open` does -- it finds the file's bits on disk and opens the door to read or write the file.
4+
5+
## File Modes
6+
7+
By default, a file is opened in *read* mode which means that it can't be altered. Also, the default is to open for reading *text*. The only required argument to `open` is the file name, but a second optional argument is a combination of characters to explain how to open the file. From the documentation for `open`:
8+
9+
````
10+
========= ===============================================================
11+
Character Meaning
12+
--------- ---------------------------------------------------------------
13+
'r' open for reading (default)
14+
'w' open for writing, truncating the file first
15+
'x' create a new file and open it for writing
16+
'a' open for writing, appending to the end of the file if it exists
17+
'b' binary mode
18+
't' text mode (default)
19+
'+' open a disk file for updating (reading and writing)
20+
'U' universal newline mode (deprecated)
21+
========= ===============================================================
22+
````
23+
24+
So if you do:
25+
26+
````
27+
fh = open('out.txt')
28+
````
29+
30+
It's the same as doing:
31+
32+
````
33+
fh = open('out.txt', 'wt')
34+
````
35+
36+
Where the combination of `wt` means `write text`. We can also read and write raw bits in `binary`, e.g., if you wanted to read the bit values of the pixels in an image.
37+
38+
I always make a distinction in the variable names for the `file` or `filename` and the *file handle* which I usually call `fh` if there's just one or maybe `in_fh` and `out_fh` if there is one for reading and one for writing, etc.
39+
40+
## STDIN, STDOUT, STDERR
41+
42+
Unix has three standard files or channels called *standard in*, *standard out*, and *standard error* which are normally written as STDIN, STDOUT, and STDERR. When you `print`, the default is that the text goes to STDOUT which you see in your terminal or REPL.
43+
44+
The `print` function takes some optional keyword arguments, one of which is `file` which has the default value of `sys.stdout`. If you wish to `print` to *standard error* (STDERR), you can use the `sys.stderr` file:
45+
46+
````
47+
print('This is an error!', file=sys.stderr)
48+
````
49+
50+
Note that you *do not* have to `open` these two special file handles. They are always available to you.
51+
52+
If you wish to write to a file on disc, you can `open` a file for writing and pass that:
53+
54+
````
55+
print('This is an error!', file=open('error.txt', 'wt'))
56+
````
57+
58+
Note that if each time you `open` a file for writing, you overwrite any existing data. If you wanted to `print` repeatedly in a program, you would either need to `open` in append mode:
59+
60+
````
61+
print('This is an error!', file=open('error.txt', 'at'))
62+
print('This is an also error!', file=open('error.txt', 'at'))
63+
````
64+
65+
Or, better yet, `open` the file at the beginning of the program, `print` as often as you like, and then `close` the file:
66+
67+
````
68+
fh = open('out.txt', 'wt')
69+
print('Writing some text.', file=fh)
70+
print('Adding more text.', file=fh)
71+
fh.close()
72+
````
73+
74+
Or use the `write` method of the file handle:
75+
76+
````
77+
fh = open('out.txt', 'wt')
78+
fh.write('Writing some text.\n')
79+
fh.write('Adding more text.\n')
80+
fh.close()
81+
````
82+
83+
Note that `print` automatically adds a newline to the end of the text whereas `write` does not so you need to add it yourself.
84+
85+
You can only *read* from STDIN. Again, you do not need to `open` it as it is always available. Treat it exactly like a file handle you've opened for reading, e.g., to read lines from STDIN until you recieve EOF (end of file):
86+
87+
````
88+
for line in sys.stdin:
89+
````

0 commit comments

Comments
 (0)