Python Concepts/Console Output
Objective
edit
This lesson on Console I/O contains material specific to Python running directly from a Unix/Linux shell. It does not apply to Python running under Windows or under popular IDEs such as IDLE or PyCharm. Many of the examples will fail in various ways under Windows or with IDEs. |
Lesson
edit
In the context of this lesson, the word "console" implies the visual display which you see in front of you when you sit at your desk, and also the keyboard. The visual display provides console output and the keyboard provides "console input."
$ cat t4.py print ('Hello, world!') # Contents of python script t4.py
$ python3.6 t4.py # Execute the python script. Hello, world! $ When the Python reserves two file objects for console output: standard output and standard error: >>> import sys
>>> sys.stdout
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
>>> sys.stderr
<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
>>>
>>> import io
>>> isinstance(sys.stdout, io.TextIOWrapper)
True
>>> isinstance(sys.stderr, io.TextIOWrapper)
True
>>>
Both of the above file objects are always open for writing in text mode. Each of the file objects has its associated file descriptor: >>> sys.stdout.fileno()
1
>>> sys.stderr.fileno()
2
File descriptor 1 usually means standard output, file descriptor 2 usually means standard error. When you write to stdout or stderr, the data written usually appears on the visual display in front of you unless their outputs are redirected. |
Writing to standard output
edit
$ cat t4.py import sys
import os
print ('line 1 to stdout ')
sys.stdout.write('line 2 to stdout ')
os.write(1, b'line 3 to stdout ')
$ python3.6 t4.py line 1 to stdout line 3 to stdout line 2 to stdout $ Line 3 was printed before line 2. To produce the expected result flush the buffer as necessary. import sys
import os
print ('line 1 to stdout ')
sys.stdout.write('line 2 to stdout ') ; sys.stdout.flush()
os.write(1, b'line 3 to stdout ')
$ python3.6 t4.py
line 1 to stdout
line 2 to stdout line 3 to stdout $
To produce acceptable output add the newline at the end of each line as necessary: import sys
import os
print ('line 1 to stdout ')
sys.stdout.write('line 2 to stdout \n') ; sys.stdout.flush()
os.write(1, b'line 3 to stdout \n')
$ python3.6 t4.py line 1 to stdout line 2 to stdout line 3 to stdout $
|
Writing to standard error
edit
import sys
import os
print (' line 1e to stderr ', file=sys.stderr)
sys.stderr.write(' line 2e to stderr \n') ; sys.stderr.flush()
os.write(2, b' line 3e to stderr \n')
$ python3.6 t4.py line 1e to stderr line 2e to stderr line 3e to stderr $ python3.6 t4.py 2>/dev/null # Standard error redirected. $ # No output to console.
|
Output streams redirected
edit
import sys
import os
print (' line 1 to stdout ')
sys.stdout.write(' line 2 to stdout \n') ; sys.stdout.flush()
os.write(1, b' line 3 to stdout \n')
print (' line 1e to stderr ', file=sys.stderr)
sys.stderr.write(' line 2e to stderr \n') ; sys.stderr.flush()
os.write(2, b' line 3e to stderr \n')
$ python3.6 t4.py # No output redirection line 1 to stdout # All output appears on the console. line 2 to stdout line 3 to stdout line 1e to stderr line 2e to stderr line 3e to stderr $ python3.6 t4.py 1>/dev/null # stdout redirected line 1e to stderr # Only stderr appears on console. line 2e to stderr line 3e to stderr $ python3.6 t4.py 2>/dev/null # stderr redirected line 1 to stdout # Only stdout appears on console. line 2 to stdout line 3 to stdout $ python3.6 t4.py 1>/dev/null 2>/dev/null # Both streams redirected. $ # No output to console. $ $ python3.6 t4.py >/dev/null # If no fd is specified, default is 1. line 1e to stderr line 2e to stderr line 3e to stderr $
|
Overriding output redirection
edit
If you wish to override output redirection so that some output goes to the terminal unconditionally, here is one way to do it: import sys
import os
print ('hello, world!') # file=sys.stdout is default
print ('Hello, World!', file=sys.stderr)
print ('Name of my terminal is:', os.ttyname(0))
f = open(os.ttyname(0), 'wt')
print ('File object opened for output to my terminal is:', f)
print ('line 1 written to terminal', file=f)
f.close()
$ python3.6 t5.py # No output redirection. hello, world! Hello, World! Name of my terminal is: /dev/ttys003 File object opened for output to my terminal is: <_io.TextIOWrapper name='/dev/ttys003' mode='wt' encoding='UTF-8'> line 1 written to terminal $ $ python3.6 t5.py >sout 2>serr # File descriptors 1 and 2 redirected line 1 written to terminal # This output was not redirected. $ $ cat sout hello, world! Name of my terminal is: /dev/ttys003 File object opened for output to my terminal is: <_io.TextIOWrapper name='/dev/ttys003' mode='wt' encoding='UTF-8'> $ $ cat serr Hello, World! $ The above code makes the following assumption: >>> os.ttyname(0) == os.ttyname(1) == os.ttyname(2)
True
>>>
If the above assumption is not valid: >>> f1 = open(os.ttyname(1), 'wt') ; f1 # Device associated with stdout.
<_io.TextIOWrapper name='/dev/ttys002' mode='wt' encoding='UTF-8'>
>>> f2 = open(os.ttyname(2), 'wt') ; f2 # Device associated with stderr.
<_io.TextIOWrapper name='/dev/ttys002' mode='wt' encoding='UTF-8'>
>>>
|
Assignments
edit
|
Further Reading or Review
edit
|
References
edit1. Python's documentation:
29.1. sys — System-specific parameters and functions: "sys.stdout," "sys.stderr,"
2. Python's methods:
"16.2.3.1. I/O Base Classes," "16.2.3.4. Text I/O"
3. Python's built-in functions:
"os.fstat(fd)," "os.fsync(fd)," "os.write(fd, str)," "os.sync()," "print(*objects, ....)"