问题描述
我创建了一个 python 程序,test.py
,如下:
import subprocess
import sys,os
FolderPath = subprocess.getoutput("cd . && pwd")
ProgramName = sys.argv[0]
LogName = ProgramName[:-3]+'_printout.txt'
ProgramFile = FolderPath+'/'+ProgramName
LogFile = FolderPath+'/'+LogName
_stdin = sys.stdin
_stdout = sys.stdout
_stderr = sys.stderr
sys.stdin = open(LogFile,'w')
sys.stdout = open(LogFile,'a')
sys.stderr = open(LogFile,'a')
Prog = open(ProgramFile,'r')
print(Prog.read())
TEST = str(input("Enter the name: \n TEST_NAME: "))
print(TEST)
sys.stdin = _stdin.flush()
sys.stdout = _stdout.flush()
sys.stderr = _stderr.flush()
使用命令 linux
在 python test.py
上执行后,我在 test_printout.txt
中遇到错误。
Enter the name:
TEST_NAME: Traceback (most recent call last):
File "test.py",line 21,in <module>
TEST = str(input("Enter the name: \n TEST_NAME: "))
io.UnsupportedOperation: not readable
import subprocess
import sys,'w+')
sys.stdout = open(LogFile,'r')
print(Prog.read())
TEST = str(input("Enter the name: \n TEST_NAME: "))
print(TEST)
sys.stdin = _stdin.flush()
sys.stdout = _stdout.flush()
sys.stderr = _stderr.flush()
但是得到了:
Enter the name:
TEST_NAME: import subprocess
它没有让我输入任何内容。我想要的是让我输入字符串并将其保存到 test_printout.txt
。
Enter the name:
TEST_NAME: This Is What I Type And Save!
有人知道怎么解决吗?
此外,如果我使用 w+
而不是 w
模式,如果我将程序更改为导入 pandas.DataFrame 并操作数据,则写入 test_printout.txt
将需要更长的时间。
有没有办法只向test_printout.txt
写简单的印刷词而不阅读整个内容?
import subprocess,sys,os
FolderPath = subprocess.getoutput("cd . && pwd")
ProgramName = sys.argv[0]
LogName = ProgramName[:-3]+'_printout.txt'
ProgramFile = FolderPath+'/'+ProgramName
LogFile = FolderPath+'/'+LogName
_stdin = sys.stdin
_stdout = sys.stdout
_stderr = sys.stderr
class stdout_Logger(object):
def __init__(self):
self.stdout = sys.stdout
self.log = open(LogFile,"a")
def write(self,message):
self.stdout.write(message)
self.log.write(message)
def flush(self):
#this flush method is needed for python 3 compatibility.
#this handles the flush command by doing nothing.
#you might want to specify some extra behavior here.
pass
sys.stdout = stdout_Logger()
class stderr_Logger(object):
def __init__(self):
self.stderr = sys.stderr
self.log = open("test_printout.txt",message):
self.stderr.write(message)
self.log.write(message)
def flush(self):
#this flush method is needed for python 3 compatibility.
#this handles the flush command by doing nothing.
#you might want to specify some extra behavior here.
pass
sys.stderr = stderr_Logger()
Prog = open(ProgramFile,'r')
print(Prog.read())
##START Program
TEST = str(input("Enter the name: \n TEST_NAME: "))
print(TEST)
#END Program
sys.stdin = _stdin.flush()
sys.stdout = _stdout.flush()
sys.stderr = _stderr.flush()
这几乎得到了我想要的。这也将我的程序保存到顶部的 test_printout.txt
并在底部执行 print(TEST)
。
但是,它还会将所有程序打印到 linux 终端控制台,这不是我想要的。我只希望它在 linux 终端中打印 "Enter the name: \n TEST_NAME: "
并且我可以输入字符串而不是打印整个程序。
我认为问题来自 sys.stdin
。
解决方法
我想我明白了。问题在于,当您在写入模式下用文件句柄替换输入时,您会禁止 input()
读取它。如果你试过这个,你会得到同样的错误:
file = open("foo.txt",'w')
content = file.read()
绕过它的方法是记录流而不重定向它们。因此,要么使用 python test.py > test_printout.txt
将控制台转储到文件中,要么创建一个记录器类来环绕流(查看此答案:How to redirect stdout to both file and console with scripting?)。
也许值得您研究日志记录模块,因为我相信它可以相当巧妙地处理这些问题。
编辑:
从您在评论中的布局来看,这就是您想要的:
import subprocess,sys,os
FolderPath = subprocess.getoutput("cd . && pwd")
ProgramName = sys.argv[0]
LogName = ProgramName[:-3]+'_printout.txt'
ProgramFile = FolderPath+'/'+ProgramName
LogFile = FolderPath+'/'+LogName
Prog = open(ProgramFile,'r')
with open(LogFile,'w') as logfile:
logfile.write(Prog.read())
_stdin = sys.stdin
_stdout = sys.stdout
_stderr = sys.stderr
class stdout_Logger(object):
def __init__(self):
self.stdout = sys.stdout
self.log = open(LogFile,"a")
def write(self,message):
self.stdout.write(message)
self.log.write(message)
def flush(self):
#this flush method is needed for python 3 compatibility.
#this handles the flush command by doing nothing.
#you might want to specify some extra behavior here.
pass
class stderr_Logger(object):
def __init__(self):
self.stderr = sys.stderr
self.log = open("test_printout.txt",message):
self.stderr.write(message)
self.log.write(message)
def flush(self):
#this flush method is needed for python 3 compatibility.
#this handles the flush command by doing nothing.
#you might want to specify some extra behavior here.
pass
sys.stdout = stdout_Logger()
sys.stderr = stderr_Logger()
##START Program
TEST = str(input("Enter the name: \n TEST_NAME: "))
print(TEST)
#END Program
sys.stdin = _stdin.flush()
sys.stdout = _stdout.flush()
sys.stderr = _stderr.flush()