Python: change sys.stdout print to custom print function

I am trying to figure out how to create a custom print function. (using python 2.7)

import sys class CustomPrint(): def __init__(self): self.old_stdout=sys.stdout #save stdout def write(self, text): sys.stdout = self.old_stdout #restore normal stdout and print print 'custom Print--->' + text sys.stdout= self # make stdout use CustomPrint on next 'print' # this is the line that trigers the problem # how to avoid this?? myPrint = CustomPrint() sys.stdout = myPrint print 'why you make 2 lines??...' 

The above code outputs to the console:

 >>> custom Print--->why you make 2 lines??... custom Print---> >>> 

and I want to print only one line:

 >>> 1custom Print--->why you make 2 lines??... >>> 

But I can’t understand how to make this work for printing, I understand that there is some kind of recursion that launches the second output to the console (I use self.write to assign stdout to self.write!)

how can i do this work? or my approach is just completely wrong ...

+4
source share
3 answers

This is not recursion. It happens that your write function is called twice, once with the text you expect, the second time only with '\n' . Try the following:

 import sys class CustomPrint(): def __init__(self): self.old_stdout=sys.stdout def write(self, text): text = text.rstrip() if len(text) == 0: return self.old_stdout.write('custom Print--->' + text + '\n') 

What I do in the above code, I add a new line character to the text passed in the first call, and make sure that the second call made by the print statement, which is designed to print a new line, does not print anything.

Now try to comment on the first two lines and see what happens:

  def write(self, text): #text = text.rstrip() #if len(text) == 0: return self.old_stdout.write('custom Print--->' + text + '\n') 
+2
source

One solution might be to use a context manager if it is localized.

 #!/usr/bin/env python from contextlib import contextmanager ################################################################################ @contextmanager def no_stdout(): import sys old_stdout = sys.stdout class CustomPrint(): def __init__(self, stdout): self.old_stdout = stdout def write(self, text): if len(text.rstrip()): self.old_stdout.write('custom Print--->'+ text) sys.stdout = CustomPrint(old_stdout) try: yield finally: sys.stdout = old_stdout ################################################################################ print "BEFORE" with no_stdout(): print "WHY HELLO!\n" print "DING DONG!\n" print "AFTER" 

The above gives:

 BEFORE custom Print--->WHY HELLO! custom Print--->DING DONG! AFTER 

The code will need to remove esp. around what the class should do WRT by setting stdout back to what it was.

+3
source

How to do from __future__ import print_function . This way you will use the Python3 print function instead of the print statement from Python2. Then you can override the print function:

 def print(*args, **kwargs): __builtins__.print("Custom--->", *args, **kwargs) 

However, there is a trick, you will need to start using the print function. A.

+1
source

All Articles