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

标签 python bash markdown

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

假设我有一个脚本 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/

相关文章:

python - 使用 websocket - Python 从 h.264 视频流中捕获第一张图像

python - 拆分数据并将其保存为文本文档

Bash 'for' 循环语法?

linux - 每条规则的运行时间

markdown - 工兵/ slim : How do I add markdown files?

python - 带有逻辑运算符的乌龟 ORM 过滤器

Python 3D 绘制测量数据

bash - 在数字列表中添加前导空格?

html - 如何将 Pandoc markdown 导出到 Worpress.com 兼容的 PHP Markdown Extra?

visual-studio-code - 在 Visual Studio Code 中编辑 Markdown 文件时如何在标题之间导航?