看来他们在 Python 3 中取消了通过删除快速加载脚本的所有简单方法 execfile()

我缺少明显的替代方案吗?

有帮助吗?

解决方案

根据文档, , 代替

execfile("./filename") 

使用

exec(open("./filename").read())

看:

其他提示

您只需阅读该文件并自己执行代码即可。2to3 当前替换

execfile("somefile.py", global_vars, local_vars)

作为

with open("somefile.py") as f:
    code = compile(f.read(), "somefile.py", 'exec')
    exec(code, global_vars, local_vars)

(编译调用并不是严格需要的,但它将文件名与代码对象关联起来,使调试更容易一些。)

看:

尽管 exec(open("filename").read()) 通常被作为替代方案 execfile("filename"), ,它错过了重要的细节 execfile 支持的。

Python3.x 的以下函数与直接执行文件具有相同的行为。与跑步相匹配 python /path/to/somefile.py.

def execfile(filepath, globals=None, locals=None):
    if globals is None:
        globals = {}
    globals.update({
        "__file__": filepath,
        "__name__": "__main__",
    })
    with open(filepath, 'rb') as file:
        exec(compile(file.read(), filepath, 'exec'), globals, locals)

# execute the file
execfile("/path/to/somefile.py")

笔记:

  • 使用二进制读取以避免编码问题
  • 保证关闭文件 (Python3.x对此发出警告)
  • 定义 __main__, ,某些脚本依赖于此来检查它们是否作为模块加载,例如。 if __name__ == "__main__"
  • 环境 __file__ 对于异常消息和某些脚本使用更好 __file__ 获取其他文件相对于它们的路径。
  • 接受可选的全局变量和局部变量参数,将它们就地修改为 execfile 确实如此 - 因此您可以在运行后通过读回变量来访问定义的任何变量。

  • 与Python2不同 execfile 这确实 不是 默认修改当前命名空间。为此,你必须显式传入 globals() & locals().

作为 在 python-dev 上建议 最近的邮件列表 奔跑的 模块可能是一个可行的替代方案。引用该消息:

https://docs.python.org/3/library/runpy.html#runpy.run_path

import runpy
file_globals = runpy.run_path("file.py")

有细微的差别 execfile:

  • run_path 总是创建一个新的命名空间。它将代码作为模块执行,因此全局变量和局部变量之间没有区别(这就是为什么只有一个 init_globals 争论)。返回全局变量。

    execfile 在当前命名空间或给定命名空间中执行。的语义 localsglobals, ,如果给定的话,类似于类定义中的局部变量和全局变量。

  • run_path 不仅可以执行文件,还可以执行eggs和目录(具体参考其文档)。

这是一个较好的,因为它需要在全局和本地居民从呼叫者:

import sys
def execfile(filename, globals=None, locals=None):
    if globals is None:
        globals = sys._getframe(1).f_globals
    if locals is None:
        locals = sys._getframe(1).f_locals
    with open(filename, "r") as fh:
        exec(fh.read()+"\n", globals, locals)

您可以编写自己的功能:

def xfile(afile, globalz=None, localz=None):
    with open(afile, "r") as fh:
        exec(fh.read(), globalz, localz)

如果您真的需要...

如果你想加载脚本是在同一目录比你运行一个,也许是“进口”将做的工作?

如果您需要动态导入代码内置功能 __ __进口和模块小鬼是值得考虑的。

>>> import sys
>>> sys.path = ['/path/to/script'] + sys.path
>>> __import__('test')
<module 'test' from '/path/to/script/test.pyc'>
>>> __import__('test').run()
'Hello world!'

test.py:

def run():
        return "Hello world!"

如果您正在使用Python 3.1或更高版本,你也应该看看的导入库

下面是我有什么(file已分配给该路径与在这两个例子中的源代码的文件):

execfile(file)

这就是我与取代它:

exec(compile(open(file).read(), file, 'exec'))

我最喜欢的部分:第二个版本工作在两个Python 2和3就好了,这意味着它没有必要在版本号的逻辑添加

请注意,上述图案将如果您使用PEP-263编码声明失败 未ASCII或UTF-8。你需要找到的数据编码,并对其进行编码 正确之前递它给exec()。

class python3Execfile(object):
    def _get_file_encoding(self, filename):
        with open(filename, 'rb') as fp:
            try:
                return tokenize.detect_encoding(fp.readline)[0]
            except SyntaxError:
                return "utf-8"

    def my_execfile(filename):
        globals['__file__'] = filename
        with open(filename, 'r', encoding=self._get_file_encoding(filename)) as fp:
            contents = fp.read()
        if not contents.endswith("\n"):
            # http://bugs.python.org/issue10204
            contents += "\n"
        exec(contents, globals, globals)

另外,虽然不是一个纯Python的解决方案,如果你使用IPython的(或许你应该是这样),你可以这样做:

%run /path/to/filename.py

这是同样容易。

我在这里只是一个新手,所以也许它是纯粹的运气,如果我发现这一点:

尝试与命令运行从解释提示>>>脚本之后

    execfile('filename.py')

针对我有一个“NameError:名称‘的execfile’没有定义”我试图一个非常基本的

    import filename

它的工作良好: - )

我希望这可以帮助,并感谢大家的伟大的提示,实例和代码的所有精湛评论作品是对新手来说有很大的启发!

我使用Ubuntu 16.014 LTS 64。 的Python 3.5.2(默认情况下,2016年11月17日,17点05分23秒) [GCC 5.4.0 20160609]在Linux

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top