Python 3 中 execfile 的替代方案?

69 投票
4 回答
113313 浏览
提问于 2025-04-16 19:36

在Python 2中,有一个内置的函数叫做execfile,但是在Python 3.0中这个函数被去掉了。这个问题讨论了Python 3.0的替代方案,不过自从Python 3.0以来,已经做了一些相当大的改动可以在这里查看

那么,对于Python 3.2以及未来的Python 3.x版本,最好的替代方案是什么呢?

4 个回答

9

在Python3.x中,这是我能想到的最接近直接执行一个文件的方法,跟运行 python /path/to/somefile.py 是一样的。

注意事项:

  • 使用二进制读取来避免编码问题
  • 确保文件会被关闭 (Python3.x对此有警告)
  • 定义了 __main__,一些脚本依赖这个来检查它们是否作为模块加载,比如 if __name__ == "__main__"
  • 设置 __file__ 对于异常信息更友好,有些脚本使用 __file__ 来获取其他文件相对于它们的路径。
def exec_full(filepath):
    global_namespace = {
        "__file__": filepath,
        "__name__": "__main__",
    }
    with open(filepath, 'rb') as file:
        exec(compile(file.read(), filepath, 'exec'), global_namespace)

# Execute the file.
exec_full("/path/to/somefile.py")
69
execfile(filename)

可以用下面的方式替换

exec(open(filename).read())

这在所有版本的Python中都能工作

较新的Python版本会提醒你没有关闭那个文件,所以如果你想消除这个警告,可以这样做:

with open(filename) as infile:
    exec(infile.read())

但其实,如果你在乎关闭文件,那你应该更在乎不要一开始就使用 exec

79

2to3 脚本的作用是将

execfile(filename, globals, locals)

替换为

exec(compile(open(filename, "rb").read(), filename, 'exec'), globals, locals)

这似乎是官方推荐的做法。你可能想使用一个 with 块,这样可以确保文件在使用完后及时关闭:

with open(filename, "rb") as source_file:
    code = compile(source_file.read(), filename, "exec")
exec(code, globals, locals)

你可以省略 globalslocals 这两个参数,这样文件会在当前的环境中执行,或者你可以使用 exec(code, {}),这样会用一个新的临时字典作为全局和局部字典,从而在一个新的临时环境中执行文件。

撰写回答