导入当前目录中的所有文件

3
我刚刚开始了一个Python项目。目录结构如下:
/algorithms  
----/__init__.py  
----/linkedlist  
--------/__init__.py  
--------/file1.py  
--------/file2.py  
/tests  
----/test_linkedlist

你也可以检查Github库
在“algorithms”文件夹下的每个子文件夹中,我在“__init__”文件中逐一为所有文件添加以下代码:
from .file1 import *
from .file2 import *

等等。我试图完成的任务是使用以下查询一起运行所有测试:
python3 -m unittest discover tests

测试目录中的每个文件都以以下内容开头:
from algorithms.linkedlist import *  
import unittest

现在,如果我想将一个新文件添加到链接列表目录中,我会创建该文件,然后在__init__文件中添加另一个from .filename import *。如何在__init__文件中编写脚本,以便每次创建新文件时,不必手动插入导入命令?
1个回答

1

那么__init__文件与此处在同一文件夹中?正如docs所说的那样:导入语句是对__import__函数的语法糖。

因此,我们可以使用:

import importlib
import glob
for file in glob.iglob('*.py'):
    importlib.__import__(file)

一些导致代码无法正常工作的原因:
  • 您想要在模块中加载函数 - 使用import * from语法。使用此代码,您只能运行file1.test
  • 您正在从另一个目录加载脚本,这会使glob混淆。我们必须指定实际的工作目录。
  • __import__更喜欢知道模块名称。
为了找到解决方案,我将this答案中的import * from函数与this博客中的pkgutil.walk_packages组合使用。
import importlib
import pkgutil 

def custom_import_all(module_name):
    """ Use to dynamically execute from module_name import * """
    # get a handle on the module
    mdl = importlib.import_module(module_name)

    # is there an __all__?  if so respect it
    if "__all__" in mdl.__dict__:
        names = mdl.__dict__["__all__"]
    else:
        # otherwise we import all names that don't begin with _
        names = [x for x in mdl.__dict__ if not x.startswith("_")]

    # now drag them in
    globals().update({k: getattr(mdl, k) for k in names})


__path__ = pkgutil.extend_path(__path__, __name__)
for importer, modname, ispkg in pkgutil.walk_packages(path=__path__, prefix=__name__+'.'):
    custom_import_all(modname)

将此内容复制并粘贴到__init__文件中失败了。是的,__init__文件与同一文件夹中。我正在尝试从包的根目录运行问题中给出的测试命令。 - Omar S
@OmarShalla 你所说的失败是指文件没有被正确地包含,导致测试失败,还是建议的代码本身就出现了错误? - FlyingTeller
建议的代码出现了错误。您可以克隆我的存储库并尝试自己运行。错误日志太长了,无法在此处发布。再次提醒,我正在从包的根目录(包含算法和测试文件夹的目录)运行以下命令'python3 -m unittest discover tests' - Omar S
现在使用你的git进行测试 :) - Roelant
感谢您的帮助! - Omar S
更新了答案。你已经通过了21个测试 ;) - Roelant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接