I'll preface this answer by suggesting that you never use this approach in real code. However, for completeness (and as it answers the original question) I thought I would add it here.
So you can redirect and catch print
statements on the fly by redirecting sys.stdout
.
You can start by defining a file-like object that catches stdout
and redirects to... stdout
.
import sys
class OutputFormatter(object):
def __init__(self,prefix="",suffix=""):
self.prefix = prefix
self.suffix = suffix
def write(self,msg):
# As you want to change the behaviour of the print statement,
# you need to ignore solitary newlines that are sent to stdout
if msg != '\n':
# reformat the message passed by print
msg = " ".join([self.prefix,msg,self.suffix])
# redirect back to stdout
sys.__stdout__.write(msg)
With this in place, you can use it to replace sys.stdout
to produce the "overridden" type of print behaviour you describe.
class Device(object):
def set_simulated(self):
# in simulated mode, use the stdout redirect
sys.stdout = OutputFormatter(prefix="[simulated]",suffix="")
def set_real(self):
# in real mode make sure to return to proper stdout
sys.stdout = sys.__stdout__
class Microcontroller(Device):
def __init__(self):
super(Microcontroller,self).__init__()
self.set_simulated()
print "This is simulated"
self.set_real()
print "This is real"
Microcontroller()
This will print the following to the terminal:
[simulated] This is simulated
This is real
Beware however that this is a global change to the behaviour of stdout
and will affect all print statements if a Device
subclass has been set to simulated mode.
A much better approach for systems like this where you require context dependent messages is to use the logging module or to take the approach suggested by BSH.