If it is allowed to modify the code inside f2, f3 then one way would be use a custom context manager which assigns sys.stdout to something else, and at exit of that context manager reassign sys.stdout to the original STDOUT.
import sys, StringIO
class Supress_print(object):
def __init__(self):
pass
def __enter__(self):
self.stdout = sys.stdout
sys.stdout = StringIO.StringIO()
def __exit__(self, *args):
sys.stdout = self.stdout
def f1():
print 'foo'
def f2(boo=True):
with Supress_print():
f1()
if boo:
print 'bar'
else:
print 'black sheep'
def f3():
with Supress_print():
f2()
print 'shh!!!'
f2(True)
print
f2(False)
print
f3()
Output:
bar
black sheep
shh!!!
Update:
import sys, inspect, functools, StringIO
def supress_print(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
#print inspect.getouterframes(inspect.currentframe())[3][3], func.__name__
if inspect.getouterframes(inspect.currentframe())[3][3] != 'main':
stdout = sys.stdout
sys.stdout = StringIO.StringIO()
val = func(*args, **kwargs)
sys.stdout = stdout
return val
else:
return func(*args, **kwargs)
return wrapper
@supress_print
def f1():
print 'foo'
@supress_print
def f2(boo=True):
f1()
if boo:
print 'bar'
else:
print 'black sheep'
def f3():
f2()
print 'shh!!!'
f2,f3?loggingcould help here.