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

时间:2019-03-07 10:12:28

标签: python

我刚开始一个python项目。目录结构如下:

/algorithms  
----/__init__.py  
----/linkedlist  
--------/__init__.py  
--------/file1.py  
--------/file2.py  
/tests  
----/test_linkedlist

您还可以选中Github repository

algorithms下的每个子文件夹中,在__init__文件中,我对所有文件都一一列出以下内容:

from .file1 import *
from .file2 import *

以此类推。

我要实现的任务是使用查询一起运行所有测试:

python3 -m unittest discover tests

tests目录中的每个文件开始如下:

from algorithms.linkedlist import *  
import unittest

现在,如果要将新文件添加到链表目录中,请先创建文件,然后在from .filename import *文件中添加另一个__init__

如何在__init__文件中编写脚本,以便每次创建新文件时都不必手动插入导入命令?

1 个答案:

答案 0 :(得分:1)

因此__init__在同一个文件夹中吗?正如docs所说的 import语句是__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)