我可以像在交互模式下输入内容一样运行Python文件吗?

3

比如我有一个 test.py 文件:

s='123'
print(s)

我希望你能够翻译出以下内容,就像我手动在python中输入一样:

>>> s='123'
>>> print(s)
123

但我想从CLI运行这个文件python test.pypython -i test.py 不会显示出来,同样的,ipython test.pyipython -i test.py 也是如此。


如果您正确设置了所有内容,“python test.py”将正常工作。当您运行它时会发生什么? - Carcigenicate
1
@imba-tjd 我不知道有没有办法让它运行并显示正在运行的代码行。这只对最小的程序有用。任何正常大小的程序都会在整个执行过程中不断输出正在运行的代码行,速度非常快,你根本无法阅读它们。这是不切实际的。 - Carcigenicate
1
据我所知,Python 没有显示其运行的代码行的函数。你需要自己编写 Python 解释器。如果您想查看正在执行哪一行,则可能需要学习如何使用调试器。 - furas
1
对于小程序,您可以在PythonTutor.com上运行它,它将显示它运行的哪一行,并显示所有变量中的值。 - furas
3
trace模块就是你想要的东西,详情请参阅https://docs.python.org/3/library/trace.html。 - hek2mgl
显示剩余2条评论
1个回答

1
将以下内容保存在名为 tracer.py 的文件中:
import sys

class Tracer(object):
    def __init__(self):
        self._filecache = {'<string>' : open(sys.argv[1], 'r').readlines() or '\n'}
        self._linecache = {'<string>' : 0}

    def accept(self, fn):
        if fn != "<string>": # from exec
            return False
        return True

    def trace(self, frame, event, arg):
        fn = frame.f_code.co_filename
        if not self.accept(fn):
            return self.trace

        if fn not in self._filecache:
          # wait until importing of the module is done to minimize pollution
            f = frame.f_back
            while f is not None:
                try:
                    if 'import' in _filecache[f.f_code.co_filename][f.f_lineno]:
                        return self.trace
                except Exception:
                     pass
                f = f.f_back
            del f

          # import is done, and we're back, accept this file from this point on
            self._filecache[fn] = open(fn, 'r').readlines() or '\n'
            self._linecache[fn] = sys.maxsize

        lno = frame.f_lineno

        ncur = self._linecache[fn]
        buf = self._filecache[fn]

        if event == 'line':
            for i in range(ncur, lno):
                ncur = self._oneline(i, buf)

            self._linecache[fn] = max(ncur, lno)

        elif event == 'return':
            if lno <= ncur:
                fln = frame.f_code.co_firstlineno - 1
                self._oneline(fln, None)
        return self.trace

    def _oneline(self, lineno, buf):
        print('>>> ', end='')

      # simple eol case
        if not buf or not buf[lineno]:
            print()
            return

      # in general, an interpreter "line" may be longer than a file line
        line = buf[lineno].rstrip()
        haseol = False
        while line and (line[-1] in ('(', '\\', ':') or line[0] in (' ', '\t')):
         # this line appears to have a continuation ...
            try:
             # output traced line
                print(line)

             # output continued line
                lineno += 1
                print('... ', end='')
                line = buf[lineno].rstrip()
            except IndexError:
             # shouldn't happen; but must mean that the diagnosis above is
             # wrong and that there is no continuation, keep silent
                break
        else:
            print(line)
            haseol = True

        if not haseol:
            print()

        return lineno

sys.settrace(Tracer().trace)
exec(open(sys.argv[1]).read())
sys.settrace(sys._getframe(0).f_trace)

将您想要跟踪的代码存储在其自己的文件中。例如,您的示例代码,名为test.py:

s = '123'
print(s)

并执行以下命令:

$ python3 tracer.py test.py

它产生所需的:


>>> s = '123'
>>> print(s)
123
>>>

我还没有进行过严格的测试,所以可能会有一些特殊情况。不过,这应该能让你开始进展。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接