python - 在所有条件下强制从文件名导入模块(更改模块、更改文件名)

标签 python python-import

我正在寻找一个Python例程,它可以从某个文件名加载并返回一个模块,即使之前导入了具有该名称或来自该文件名的模块。

更具体地说,我想编写一个通过以下测试的函数unconditional_import:

import os

def make_module(folder, filename, version):
    try: os.mkdir(folder)
    except OSError: pass

    f = open(os.path.join(folder,filename), "w")
    f.write("version = %i" % version)
    f.close()

make_module("test","spam.py", 1)
assert( unconditional_import("test","spam.py").version == 1 )

make_module("test","more_spam.py", 2)
assert( unconditional_import("test","more_spam.py").version == 2 )

make_module("test","more_spam.py", 3)
assert( unconditional_import("test","more_spam.py").version == 3 )

make_module("test2","more_spam.py", 4)
assert( unconditional_import("test2","more_spam.py").version == 4 )

我找到了一个解决方案(我将发布它作为保持事情结构化的答案),但它相当丑陋并且感觉不稳健。我希望有一些更简单、原生的方法来做到这一点,但我找不到它。

注释:

  • 我知道 How to import a module given the full path? ,它解决了如何从路径导入模块,但只能运行一次。

  • 我知道在大多数情况下,人们只会重新加载解释器,但这对我来说不是一个选择。

最佳答案

到目前为止我最好的解决方案是:

def unconditional_import(folder, filename):
    full_path = os.path.join(folder,filename)

    if os.path.isfile(full_path+"c"):
        os.remove(full_path+"c")

    cachefolder = os.path.join(folder,"__pycache__")
    if os.path.isdir(cachefolder):
        for f in os.listdir(cachefolder):
            if f.startswith(filename.rstrip(".py")) and f.endswith(".pyc"):
                os.remove(os.path.join(cachefolder,f))

    if sys.version_info < (3,0):
        from imp import load_source
        foo = load_source("foo", full_path)

    elif sys.version_info < (3,5):
        from importlib.machinery import SourceFileLoader
        foo_module = SourceFileLoader("foo", full_path)
        foo = foo_module.load_module()

    else:
        from importlib.util import spec_from_file_location, module_from_spec
        spec = spec_from_file_location("foo", full_path)
        foo = module_from_spec(spec)
        spec.loader.exec_module(foo)

    return foo

问题和注意事项:

  • 我无法测试 Python 3.5 及更高版本的变体,但我认为没有理由它不起作用,或者为什么会有更简单的解决方案。

  • 手动删除 PYC 文件让我感到畏缩,我预计它会导致问题。

关于python - 在所有条件下强制从文件名导入模块(更改模块、更改文件名),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36964387/

相关文章:

python - 为什么不允许在函数中使用 "from ... import *"?

python - 在 Pandas DataFrame 列中进行整数编码后将 dtype 保留为类别

python - 将命令行参数从文件夹脚本传递到文件脚本

python - 在 Python 中挂载单词出现列表的有效方法

Python 并行线程

Python+sqlite : the LIKE query with wildcards

python - 如何从父子目录导入模块

Python 2.7 ImportMismatchError 在 basedir 重命名后由过时的 pycache 引起

python - 如何使用 if __name__ ='__main__' block 在 Python3 中使用相对导入?

python - 如何在 Jupyter Notebook 中创建模块并导入它们? Python