Python 将所有第三方软件包和脚本作为通用软件包轻松导入?
我想在我的程序中添加一个Python 将所有第三方软件包和脚本作为通用软件包轻松导入?,python,python-3.x,import,Python,Python 3.x,Import,我想在我的程序中添加一个外部包,其中应该包括它使用的所有配方和第三方包。我不想强迫任何人(包括我自己)安装这些软件包,更不用说版本不兼容了。我只是 希望将它们放在自己的子文件夹中并使用它们。他们,, 当然,来自不同的来源 文件夹结构应如下所示: | main.py |---[external] |---[networkx] | | ... |---[xlrd] | | ... | __init__.py | recipe1.py |
外部
包,其中应该包括它使用的所有配方和第三方包。我不想强迫任何人(包括我自己)安装这些软件包,更不用说版本不兼容了。我只是
希望将它们放在自己的子文件夹中并使用它们。他们,,
当然,来自不同的来源
文件夹结构应如下所示:
| main.py
|---[external]
|---[networkx]
| | ...
|---[xlrd]
| | ...
| __init__.py
| recipe1.py
| recipe2.py
我想在我的计划中通过以下方式了解套餐和食谱:
import external
import external.xlrd
from external import networkx as nx
import external.recipe1
from external import recipe2 as magic
from external import *
但是,任何包都可能包含绝对导入,这可能导致importorror
假设external
有一个空的\uuuu init\uuuuuuuuuuuupy
:
>>> import external.networkx
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".\external\networkx\__init__.py", line 46, in <module>
from networkx import release
ImportError: No module named 'networkx'
导入外部.networkx
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“\external\networkx\\uuuuu init\uuuuuu.py”,第46行,在
从networkx导入发布
ImportError:没有名为“networkx”的模块
有没有一种简单的方法来制作这样一个外部包?我制作了一个函数来实现这一点。您只需将此行放入外部文件夹的
\uuuu init\uuuuu.py
:
__all__ = import_all(__path__)
此函数通常可用于导入所有子模块,即使它们是嵌套的,只需将其放入所有涉及的\uuuu init\uuuu.py
如果你知道一个更干净的问题解决方案,请与我们分享!我不会接受我自己的答案
from os import listdir
from os.path import abspath, basename, exists, isdir, join, \
relpath, sep, splitext
from sys import path
def import_all(path__here):
"""Imports all subpackages and submodules, excluding .py
files starting with an underscore. The directories have to
have an __init__.py to get imported.
Add this line to the __init__.py:
__all__ = import_all(__path__)"""
result, packagepath = [], relpath(path__here[0])
for e in listdir(packagepath):
mod_path = join(packagepath, e)
mod_name = splitext(basename(e))[0]
file_to_import = (e.endswith(".py")
and not mod_name.startswith("_"))
dir_to_import = (isdir(mod_path)
and exists(join(mod_path, "__init__.py")))
if not file_to_import and not dir_to_import:
continue
im_str = ".".join(mod_path.split(sep)[:-1] + [mod_name])
try:
__import__(im_str)
except ImportError as err:
# In case of a subpackage countains absolute imports
# assuming it is in the root, we put it into the
# system path and try again.
if abspath(packagepath) not in path:
path.insert(0, abspath(packagepath))
__import__(im_str)
else:
raise err from None
result.append(mod_name)
return result