gpt4 book ai didi

Python 将命令及其输出写入文件

转载 作者:行者123 更新时间:2023-12-02 11:16:42 24 4
gpt4 key购买 nike

有没有办法将命令及其输出写入外部文件?

假设我有一个脚本 outtest.py :

import random
from statistics import median, mean

d = [random.random()**2 for _ in range(1000)]
d_mean = round(mean(d), 2)
print(f'mean: {d_mean}')
d_median = round(median(d), 2)
print(f'median: {d_median}')

现在,如果我只想捕获它的输出,我知道我可以这样做:
python3 outtest.py > outtest.txt

但是,这只会给我一个 outtest.txt 文件,例如:
mean: 0.34
median: 0.27

我正在寻找的是一种获取输出文件的方法,例如 :
import random
from statistics import median, mean

d = [random.random()**2 for _ in range(1000)]
d_mean = round(mean(d), 2)
print(f'mean: {d_mean}')
>> mean: 0.34
d_median = round(median(d), 2)
print(f'median: {d_median}')
>> median: 0.27

或其他格式( Markdown ,无论如何)。本质上,类似于 jupyter notebook 或 Rmarkdown 但使用标准 .py 文件。

有没有简单的方法来实现这一点?

最佳答案

这是我刚刚编写的一个脚本,它非常全面地捕获打印输出并将其与代码一起打印,无论它是如何打印的或一次打印多少。它使用 ast模块来解析 Python 源代码,一次执行一个语句(有点好像它被馈送到 REPL),然后打印每个语句的输出。 Python 3.6+(但很容易修改为例如 Python 2.x):

import ast
import sys

if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <script.py> [args...]")
exit(1)

# Replace stdout so we can mix program output and source code cleanly
real_stdout = sys.stdout
class FakeStdout:
''' A replacement for stdout that prefixes # to every line of output, so it can be mixed with code. '''
def __init__(self, file):
self.file = file
self.curline = ''

def _writerow(self, row):
self.file.write('# ')
self.file.write(row)
self.file.write('\n')

def write(self, text):
if not text:
return
rows = text.split('\n')
self.curline += rows.pop(0)
if not rows:
return
for row in rows:
self._writerow(self.curline)
self.curline = row

def flush(self):
if self.curline:
self._writerow(self.curline)
self.curline = ''

sys.stdout = FakeStdout(real_stdout)

class EndLineFinder(ast.NodeVisitor):
''' This class functions as a replacement for the somewhat unreliable end_lineno attribute.

It simply finds the largest line number among all child nodes. '''

def __init__(self):
self.max_lineno = 0

def generic_visit(self, node):
if hasattr(node, 'lineno'):
self.max_lineno = max(self.max_lineno, node.lineno)
ast.NodeVisitor.generic_visit(self, node)

# Pretend the script was called directly
del sys.argv[0]

# We'll walk each statement of the file and execute it separately.
# This way, we can place the output for each statement right after the statement itself.
filename = sys.argv[0]
source = open(filename, 'r').read()
lines = source.split('\n')
module = ast.parse(source, filename)
env = {'__name__': '__main__'}

prevline = 0
endfinder = EndLineFinder()

for stmt in module.body:
# note: end_lineno will be 1-indexed (but it's always used as an endpoint, so no off-by-one errors here)
endfinder.visit(stmt)
end_lineno = endfinder.max_lineno
for line in range(prevline, end_lineno):
print(lines[line], file=real_stdout)
prevline = end_lineno
# run a one-line "module" containing only this statement
exec(compile(ast.Module([stmt]), filename, 'exec'), env)
# flush any incomplete output (FakeStdout is "line-buffered")
sys.stdout.flush()

这是一个测试脚本:

print(3); print(4)
print(5)

if 1:
print(6)

x = 3
for i in range(6):
print(x + i)

import sys
sys.stdout.write('I love Python')

import pprint
pprint.pprint({'a': 'b', 'c': 'd'}, width=5)

结果:

print(3); print(4)
# 3
# 4
print(5)
# 5

if 1:
print(6)
# 6

x = 3
for i in range(6):
print(x + i)
# 3
# 4
# 5
# 6
# 7
# 8

import sys
sys.stdout.write('I love Python')
# I love Python

import pprint
pprint.pprint({'a': 'b', 'c': 'd'}, width=5)
# {'a': 'b',
# 'c': 'd'}

关于Python 将命令及其输出写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60297105/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com