How do you find where the print statement is?

I have a program depending on a large code base that prints a lot of unnecessary and annoying messages. I would clean them up a bit, but since their contents are dynamically generated, I can't just grep for them.

Is there any way to place the hook in the print instruction? (I am using python 2.4, but I am interested in the results for any version). Is there any other way to find from which the output of "print" is output?

+4
source share
5 answers

For CPython2.5 and later:

import sys import inspect import collections _stdout = sys.stdout Record = collections.namedtuple( 'Record', 'frame filename line_number function_name lines index') class MyStream(object): def __init__(self, target): self.target = target def write(self, text): if text.strip(): record = Record(*inspect.getouterframes(inspect.currentframe())[1]) self.target.write( '{f} {n}: '.format(f = record.filename, n = record.line_number)) self.target.write(text) sys.stdout = MyStream(sys.stdout) def foo(): print('Hi') foo() 

gives

 /home/unutbu/pybin/test.py 20: Hi 

For CPython2.6 +, we can import the print function using

 from __future__ import print_function 

and then redirect it as you wish:

 from __future__ import print_function import sys import inspect import collections Record = collections.namedtuple( 'Record', 'frame filename line_number function_name lines index') def myprint(text): if text.strip(): record = Record(*inspect.getouterframes(inspect.currentframe())[1]) sys.stdout.write('{f} {n}: '.format(f = record.filename, n = record.line_number)) sys.stdout.write(text + '\n') def foo(): print('Hi') print = myprint foo() 

Note that inspect.currentframe uses sys._getframe , which is not part of all Python implementations. Thus, the solution above can only work for CPython.

+3
source

Strictly speaking, the code base you depend on, as in libraries, should not contain any print statements. Thus, you should simply delete all of them.

In addition, you can install the monkey patch stdout : Adding a date and time stamp to print in Python

+3
source

it’s very rude to crack this job:

use your favorite text editor, use the search / search function.

find all print statements. A.

and enter the number or identifier manually in each of them. (or automatically if you do that script)

a script to do this would be simple, just try print with a regular expression and replace it with print ID, , and then everything will be the same, but you will get the numbers.

greetings.

change

Forbid any weird formatting, the following code should do it for you.

Notice this is just an example of how you could do this. not really an answer.

 import re class inc(): def __init__(self): self.x = 0 def get(self): self.x += 1 return self.x def replacer(filename_in, filename_out): i = inc() out = open(filename_out, 'w') with open(filename_in) as f: for line in f: out.write("%s\n" % re.sub(r'print', 'print %d,' % i.get(), line)) 

I used the base class incrementer if you wanted to have some kind of more complex identifier, and not just have a counter.

+2
source

Here's the trick Jeeeyul came up with for Java : replace the output stream (i.e. sys.out ) with what it notices when the line was written.

If this flag is true, throw an exception when the next byte is written. Catch the exception in the same place, go to the stack trace until you find a code that does not belong to your "debug stream writer".

pseudo code:

 class DebugPrintln: def __init__(self): self.wasLF = False def write(self, x): if self.wasLF: self.wasLF = False frames = traceback.extract_stack() ... find calling code and output it ... if x == '\n': self.wasLF = true super.write(x) 
+1
source

In harsh circumstances (the output is done in some weird binary libraries) you can also use strace -e write (and more options). If you do not read the output of strace, the program waits until you do this, so you can send a signal and see where it dies.

+1
source

Source: https://habr.com/ru/post/1447756/


All Articles