首页 文章

什么是Python 3中execfile的替代品?

提问于
浏览
258

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

是否有一个明显的选择我错过了?

12 回答

  • 283

    这就是我所拥有的( file 已经分配给文件的路径,并在两个示例中都包含源代码):

    execfile(file)
    

    这是我用它取代的:

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

    我最喜欢的部分:第二个版本在Python 2和3中都运行良好,这意味着没有必要添加依赖于版本的逻辑 .

  • -3

    According to the documentation,而不是

    execfile("./filename")
    

    使用

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

    看到:

  • 190

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

    尝试使用命令从解释器提示符>>>运行脚本

    execfile('filename.py')
    

    我得到了一个“NameError:name'execfile'没有定义”我尝试了一个非常基本的

    import filename
    

    它工作得很好:-)

    我希望这对您有所帮助,并感谢大家提供的精彩提示,示例和所有那些精心评论的代码,这对新手来说是一个很好的灵感!

    我使用Ubuntu 16.014 LTS x64 . 在Linux上的Python 3.5.2(默认,2016年11月17日,17:05:23)[GCC 5.4.0 20160609]

  • 17

    找到文件夹安装的路径(我将它放在C:\ python34中)然后在常规cmd shell上执行

    set path=%path%;c:\python34
    

    现在,当你初始化一个shell时,转移到C:\ python34 \ myscripts并使用经典命令

    python filename.py
    
  • 42

    最近作为suggested on the python-dev邮件列表,runpy模块可能是一个可行的选择 . 引用该消息:

    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 的语义(如果给定)类似于类定义中的locals和globals .

    • run_path 不仅可以执行文件,还可以执行鸡蛋和目录(有关详细信息,请参阅其文档) .
  • 11

    你可以编写自己的函数:

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

    如果你真的需要...

  • 5

    这个更好,因为它接受来自调用者的全局变量和本地变量:

    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)
    
  • 16

    您应该自己阅读文件并执行代码 . 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)
    

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

    看到:

  • 41

    虽然 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")
    

    Notes:

    • 使用二进制读取来避免编码问题

    • 保证关闭文件(Python3.x警告这个)

    • 定义 __main__ ,一些脚本依赖于此来检查它们是否作为模块加载,例如 . if __name__ == "__main__"

    • setting __file__ 对于异常消息更好,一些脚本使用 __file__ 来获取相对于它们的其他文件的路径 .

    • 采用可选的全局变量和局部变量参数,就像 execfile 那样就地修改它们 - 所以你可以通过在运行后读回变量来访问任何定义的变量 .

    • 与Python2的 execfile 不同,默认情况下 not 修改当前命名空间 . 为此,你必须明确传入 globals() .

  • 3

    此外,虽然不是纯Python解决方案,但如果您正在使用IPython(无论如何都应该如此),您可以:

    %run /path/to/filename.py
    

    这同样容易 .

  • 1

    如果要加载的脚本与您运行的脚本位于同一目录中,那么“import”可能会完成这项工作吗?

    如果需要动态导入代码,内置函数__ import__和模块imp值得一看 .

    >>> 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或更高版本,则还应该查看importlib .

  • 7

    请注意,如果您使用的不是ascii或utf-8的PEP-263编码声明,则上述模式将失败 . 您需要找到数据的编码,并在将其传递给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)
    

相关问题