我想知道是否有办法将python脚本的输入和输出都重定向到一个文件中,这样它们就可以交错了。从本质上说,我有以下代码:
x = 1
print("hello, world")
print(x)
x = 2
print(x)
def myfun(Val):
return(Val+1)
myfun(7)
我将寻找以下内容显示在输出文件中
x = 1
print("hello, world")
"hello, world"
print(x)
1
x = 2
print(x)
2
def myfun(Val):
return(Val+1)
myfun(7)
8
我已经看过的内容包括:
python myfile.py > output.log
,但是这并不能捕获输入python -m trace myfile.py
,但是这显示了太多的信息并且使运行时变得臃肿。我找不到任何明显的方法来限制这只是顶层代码(不是每个模块和函数调用)理想情况下,我希望能找到某种具有重定向的bash魔法,一个python命令行选项,或者一个能够处理这个问题的通用python模块,但到目前为止还没有成功:
编辑:作为一个进一步澄清的例子,我试图从R重新创建以下功能。假设我们有R程序myprog.R
为:
myfun <- function(x){
x + 1
}
y <- myfun(7)
print("hello,world!")
print(y)
y + 1
然后,从命令行运行R CMD BATCH myprog.R
会生成文件myprog.Rout
,如下所示
myfun <- function(x){
x + 1
}
y <- myfun(7)
print("hello,world!")
[1] "hello,world!"
print(y)
[1] 8
y + 1
[1] 9
发布于 2018-06-06 04:49:47
编辑这是一个非常有限的脚本,不幸的是,如果你的代码变得更复杂(意味着语句跨越多行),就会立即中断,就像拥有一个函数一样简单。
对于非常简单的示例用例,您可以使用一个中间脚本,如下所示(假设文件名为rt.py):
import sys
in_file = sys.argv[1]
with open(in_file) as script:
for line in script:
line = line.strip()
if line:
# Option to visually separate it by using repr
# print(repr(line))
print(line)
# Another optional use a prefix
# print(">>>", end="")
exec(line)
现在,您可以将现有脚本传递给它
python rt.py somescript.py
这将不是不可能增强这一点,以准备基于缩进的脚本,但这可能是不值得的,我希望存在其他解决方案,我不知道。
发布于 2018-06-06 04:53:51
假设输入文件名为a.py
,这将重定向eval调用的stdout,以便捕获该文件,然后将其与源文件一起写入文件(out.py
)。
就像dparolin所说的,虽然这对于简单的脚本是有效的,但是一旦你有了块,事情就会崩溃。
import sys
from io import StringIO
import contextlib
filename="a.py"
f= open(filename,"r")
f_out= open("out.py","w+")
SCRIPT_LOCALS={}
@contextlib.contextmanager
def stdoutIO(stdout=None):
old = sys.stdout
if stdout is None:
stdout = StringIO()
sys.stdout = stdout
yield stdout
sys.stdout = old
def eval_with_return(str_code):
with stdoutIO() as s:
exec(str_code,SCRIPT_LOCALS)
return s.getvalue()
for line in f:
orig_line=line if line.endswith("\n") else line+"\n"
sys_out_res=eval_with_return(line)
f_out.write(orig_line)
f_out.write(sys_out_res)
f.close()
f_out.close()
发布于 2018-06-06 05:10:00
作为另一种选择,您可以解析跟踪模块创建的输出,并删除您不喜欢的部分。在本例中,我将自己限制在前缀和模块打印输出上。要小心,因为没有格式正确的(PEP8)代码,这也很容易删除函数定义,但是这可能是一个特性,而不是错误;-)在其默认使用中,trace不会给出函数内容。这取决于你到底需要什么。
将以下代码另存为trace_rt.py并按如下方式使用
python -m trace -t yourfile.py | trace_rt.py
trace_rt.py:
import sys
def cutoff(in_line):
"""Removes trace prefix if present"""
if "): " in line:
return line.split("): ")[1]
elif line.startswith("--- modulename:"):
return ""
return line
for line in sys.stdin:
line = line.strip()
if line:
print(cutoff(line))
https://stackoverflow.com/questions/50708380
复制相似问题