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."


The simplest way to write to the console or visual display is python's print function.

$ cat t4.py
print ('Hello, world!') # Contents of python script t4.py
$ python3.6 t4.py # Execute the python script.
Hello, world! 
$

When the print statement in the script was executed, the string 'Hello, world!' appeared on the visual display in front of us. In technical terms the string was written to standard output, usually the console.

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

edit

1. 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, ....)"