【问题标题】:Importing Python scripts iteratively from relative directories从相关目录迭代导入 Python 脚本
【发布时间】:2020-03-21 03:47:21
【问题描述】:

我有一个名为test.py 的脚本,代码如下(我已经大大简化了事情):

from foo import Bar

bar = Bar()
result = bar.do_something()

但我不只是有一个名为foo 的脚本。我有许多名为foo 的脚本,按以下目录结构组织:

└── project
    ├── code
    │   ├── test.py
    └── scripts
        ├── script_1
            └── foo.py
        ├── script_2
            └── foo.py
        ├── script_3
            └── foo.py
        ├── script_4
            └── foo.py
        ├── script_5
            └── foo.py

每个foo.py 的实现略有不同。而我想用test.py 做的是通过导入每个脚本并在其上运行一些测试来测试所有脚本。下面是一些代码(*表示伪代码)

*Get all script directories*
*For each directory in script directories:*
    *import foo.py from this directory*

    bar = Bar()
    result = bar.do_something()

    *Save the result for this directory*

我该怎么做?特别是,我如何迭代地导入脚本,例如, *import foo.py from this directory*?

【问题讨论】:

标签: python python-3.x


【解决方案1】:

我建议您更改脚本为它们创建一个包,如图here。然后您可以简单地单独访问每个脚本:

import scripts.script_1.foo

from scripts.script_1 import foo

迭代导入:

要遍历文件夹并导入它们,您可以使用 python 的“importlib”库。您将需要使用来自this library 的“import_module”函数。话虽如此,您仍然需要在每个目录中包含 __init__.py 。 here 说明了使用此函数导入模块的示例。

【讨论】:

  • 谢谢。我已经尝试过了,但是在您的示例中,我必须手动记下脚本目录的名称(script_1、script_2、script_3 ...)。相反,我希望能够创建一个目录列表,然后遍历它们并在每个循环中导入“foo”。我怎样才能做到这一点?我尝试将目录列表创建为字符串,但这不起作用。
  • 我明白了,那么您需要使用 python 的 importlib 库来遍历您的文件夹。但是,此库仅用于测试。你可以在这里找到相关信息:docs.python.org/3/library/…
  • @Karnivaurus 我在原始答案中添加了有关如何实现迭代导入的更多信息。我希望这会有所帮助。
【解决方案2】:

我不得不做几件不同的事情,但生成的代码 sn-p 看起来像这样:

import os, sys, importlib

# directory of your script folder
scripts_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))+"/../scripts/")


for root, dirs, files in os.walk(scripts_dir):
    # traverse the folder and find ones that has foo.py
    if 'foo.py' in files:
        sys.path.append(root)
        out = importlib.import_module('foo', package=root)

        # call the function in foo.py.  
        #In this case, I assumed there is a function called test 
        met = getattr(out, 'test')
        print(met())

        # clean up the path and imported modules
        sys.path.remove(root)
        del sys.modules['foo']

【讨论】:

    猜你喜欢
    • 2012-06-21
    • 2016-08-01
    • 2012-05-03
    • 2018-08-03
    • 2021-08-15
    • 2020-03-28
    • 1970-01-01
    • 2014-03-22
    相关资源
    最近更新 更多