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

2024-12-09 08:30:00
admin
原创
168
摘要:问题描述:看来他们在 Python 3 中通过删除取消了所有快速加载脚本的简便方法execfile()。我是否遗漏了其他明显的替代方案?解决方案 1:根据文档,而不是execfile("./filename") 使用exec(open("./filename").re...

问题描述:

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

我是否遗漏了其他明显的替代方案?


解决方案 1:

根据文档,而不是

execfile("./filename") 

使用

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

看:

  • Python 3.0 中的新功能

  • execfile

  • exec

解决方案 2:

你只需要自己读取文件并执行代码。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)

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

看:

解决方案 3:

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

解决方案 4:

正如最近在 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`locals在当前命名空间或给定命名空间中执行。和的语义(globals`如果给出)类似于类定义中的局部和全局。

  • run_path不仅可以执行文件,还可以执行eggs和目录(详情请参阅其文档)。

解决方案 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()+"
", globals, locals)

解决方案 6:

你可以编写自己的函数:

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

如果你真的需要...

解决方案 7:

如果您要加载的脚本与您运行的脚本位于同一目录中,也许“导入”可以完成这项工作?

如果您需要动态导入代码,内置函数__ 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!'

测试.py:

def run():
        return "Hello world!"

如果您使用的是 Python 3.1 或更高版本,您还应该查看importlib。

解决方案 8:

这是我所得到的(file在两个示例中都已分配给包含源代码的文件的路径):

execfile(file)

这是我将其替换为的内容:

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

我最喜欢的部分:第二个版本在 Python 2 和 3 中都能很好地运行,这意味着不需要添加与版本相关的逻辑。

解决方案 9:

尽量避免exec()。对于大多数应用程序来说,使用 Python 的导入系统更为简洁。

该函数使用内置函数importlib将文件作为实际模块执行:

from importlib import util

def load_file_as_module(name, location):
    spec = util.spec_from_file_location(name, location)
    module = util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

使用示例

我们有一个文件foo.py

def hello():
    return 'hi from module!'
print('imported from', __file__, 'as', __name__)

并将其作为常规模块导入:

>>> mod = load_file_as_module('mymodule', './foo.py')
imported from /tmp/foo.py as mymodule
>>> mod.hello()
hi from module!
>>> type(mod)
<class 'module'>

优点

这种方法不会污染命名空间或干扰您的,$PATHexec()直接在当前函数的上下文中运行代码,可能会导致名称冲突。此外,模块属性(如__file__和)__name__将正确设置,并且代码位置将保留。因此,如果您附加了调试器或模块引发异常,您将获得可用的回溯。

请注意,与静态导入的一个小区别是,每次运行时都会导入(执行)模块load_file_as_module(),而不仅仅是使用import关键字时导入(执行)一次。

解决方案 10:

请注意,如果您使用的 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("
"):
            # http://bugs.python.org/issue10204
            contents += "
"
        exec(contents, globals, globals)

解决方案 11:

此外,虽然这不是一个纯 Python 解决方案,但如果您使用 IPython(您可能应该使用),您可以执行以下操作:

%run /path/to/filename.py

这同样容易。

解决方案 12:

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

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

    execfile('filename.py')

我得到了一个“NameError:名称‘execfile’未定义”我尝试了一个非常基本的

    import filename

效果很好:-)

我希望这可以有所帮助,并感谢大家提供的出色提示、示例和所有那些对新手有很大启发的精彩代码片段!

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

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用