是否可以从 Python 中的另一个文件执行缩进行?

Is it possible to execute indented lines from another file in Python?

说,我有两个文件demo.py

# demo.py
from pathlib import Path
for i in range(5):
    exec(Path('another_file.txt').read_text())

another_file.txt(注意缩进)

    print(i)

是否可以python demo.py 运行?

N.B。这在使用 Page(或 wxformbuilder 或 pyqt 的设计器)生成 GUI 布局时非常有用,其中自动生成回调函数的骨架。必须修改骨架,同时,每次迭代都会覆盖骨架——必须将代码片段复制回去。不管怎样,如果你用过 Page 或 wxformbuilder 或 pyqt 的设计器,你就知道我在说什么了。

您可以通过删除缩进来解决基本问题:

from pathlib import Path
import textwrap
for i in range(5):
    exec(textwrap.dedent(Path('another_file.txt').read_text()))

这里还有两个比较大的问题:

这里存在严重的安全隐患。您正在 运行ning 代码但未将其包含在您的项目中。你可以 "worry about security and other issues later" 的想法会让你在以后感到痛苦。您会在此站点上看到类似的避免 SQL 注入的建议。那个更晚的日期可能永远不会到来,即使它到来了,您也很可能不会记住或正确识别所有问题。最好能在第一时间避免问题。

此外,对于这样的动态代码,您 运行 非常真实的风险是 运行 调用堆栈出现语法错误,而该调用堆栈不显示代码的来源。这对于像这样的简单案例来说还不错,但是随着您向这样的项目添加越来越多的复杂性,您可能会发现您正在添加更多支持来帮助您调试 运行 遇到的问题,而不是花钱您有时间添加功能。

而且,将这两个问题结合起来会很有趣。它是人为设计的,但是如果您将 for 循环更改为 while 循环,如下所示:

i = 0
while i < 5:
    exec(textwrap.dedent(Path('another_file.txt').read_text()))
    i += 1

然后将文本文件修改为:

    print(i)
    i += 1

理解为什么它不再运行您预期的 5 次是微不足道的,但是随着这个项目的两个 "sides" 变得更加复杂,弄清楚元素之间复杂的相互作用将变得更加困难。

总之,不要使用eval。未来你会感谢过去的你让你的生活更轻松。