Hi,
I am using Python 2.4 on Windows.

I'm trying to save the contents of the debug window. I managed to redirect all print statements so that it prints on the debug window as well as saves a copy into a text file. The code is shpwn below:

import sys
import string

open('C:\Users\djeganat\Desktop\\todo.txt', 'w').close() 

class RedirectOutput:

    def __init__(self, stdout):
        self.stdout = stdout

    def write(self, s):
        self.stdout.write(s)
        f = open('C:\Users\djeganat\Desktop\\todo.txt', 'a')
        f.write(s)
        f.close()

# redirect standard output
sys.stdout = RedirectOutput(sys.stdout)


print "abcd",
print "\n xyz"
var = raw_input("Enter something: ")

This works perfectly fine but does not save the user input. I understand that in order to do this I need to redirect stdin. But, I don't seem to be doing it right. Could you show me?

Thanks!

Dani AI

Generated

Good catch, . The TypeError you hit comes from returning nothing from readline(); raw_input() expects a real string (and EOF must be an empty string). is right that raw_input() only calls sys.stdin.readline() in 2.x, so a file-like wrapper is enough. Two small robustness tweaks will make this solid: keep the log file open instead of reopening each write, and implement flush/softspace for stdout so print behaves like a real file.

Here is a compact, Python 2.4-friendly tee that logs both output and what the user typed. Note the raw Windows path string to avoid backslash escapes.

import sys

log = open(r'C:\Users\djeganat\Desktop\todo.txt', 'a')

class TeeOut(object):
    def __init__(self, real, logfh):
        self._real, self._log = real, logfh
        self.softspace = 0  # used by print in Py2
    def write(self, s):
        self._real.write(s)
        self._log.write(s)
    def writelines(self, seq):
        for s in seq: self.write(s)
    def flush(self):
        self._real.flush(); self._log.flush()

class TeeIn(object):
    def __init__(self, real, logfh):
        self._real, self._log = real, logfh
    def readline(self, n=-1):
        s = self._real.readline(n)
        if s: self._log.write(s); self._log.flush()
        return s

sys.stdout = TeeOut(sys.stdout, log)
sys.stdin  = TeeIn(sys.stdin,  log)

# ... your prints and raw_input() calls ...
# Remember: raw_input() returns the line WITHOUT the trailing newline.

If you prefer not to log the prompt text (because stdout is teed), another simple route is to monkey-patch raw_input() itself so only the user’s response is written. In Py2.4: import builtin, save builtin.raw_input, call it, write the returned string plus "\n" to the log, then return it. Use try/finally to restore stdin/stdout at the end if this runs inside a larger app.

Recommended Answers

All 6 Replies

I think you could try and use my brand new module 'adaptstrings', see here http://www.daniweb.com/software-development/python/code/389929 . The following code works from me

from adaptstrings import adapt_as_opener
import sys

@adapt_as_opener
def redirected_input(ifh, filename):
    with open(filename, "w") as ofh:
        while True:
            line = ifh.readline()
            ofh.write(line)
            yield line
            
sys.stdin = redirected_input(sys.stdin, "foo.txt")

for i in range(10):
    s = raw_input("Enter something: ")
    print "received ", s

Some small changes may be necessary for python 2.4 however, can't you upgrade ?

Sadly, I can't upgrade :(. But, thanks a ton for your help :)

Is there any way I could do it just the way I've done it for stdout?

Is there any way I could do it just the way I've done it for stdout?

Apparently yes, you can, as long as you only use raw_input(). By tracing the previous code, I saw that it only calls readline(), so you can define a class with a readline() method

import sys

class Redir(object):
    def __init__(self, ifh, ofh):
        self.ifh, self.ofh = ifh, ofh
    def readline(self):
        line = self.ifh.readline()
        if line:
            self.ofh.write(line)
        return line
    

sys.stdin = Redir(sys.stdin, open("foo.txt", "w"))

for i in range(10):
    s = raw_input("Enter something: ")
    print "received: ", s

Ok, this is what I did.

import sys
import string

open('C:\Users\djeganat\Desktop\\todo.txt', 'w').close() 

class RedirectOutput:

    def __init__(self, stdout):
        self.stdout = stdout

    def write(self, s):
        self.stdout.write(s)
        f = open('C:\Users\djeganat\Desktop\\todo.txt', 'a')
        f.write(s)
        f.close()

class RedirectInput:

    def __init__(self, stdin):
        self.stdin = stdin

    def readline(self):
        ss = self.stdin.readline()
        ss = str(ss)
        f = open('C:\Users\djeganat\Desktop\\todo.txt', 'a')
        f.write(ss)
        f.close()


# redirect standard output
sys.stdout = RedirectOutput(sys.stdout)
sys.stdin = RedirectInput(sys.stdin)


print "abcd",
print "\n xyz"
var = raw_input("Enter something: ")

But, I get an error

Traceback (most recent call last):
File "C:\Users\djeganat\Desktop\", line 37, in ?
var = raw_input("Enter something: ")
TypeError: object.readline() returned non-string

Can you tell me what I did wrong?

Thanks!

Add return ss at the end of readline(). Also you don't need ss = str(ss). And don't write ss if it is then empty string.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.