如何加载文件夹中的所有模块?
有人可以为我提供一种导入整个模块目录的好方法吗?
我有这样的结构:
/Foo
bar.py
spam.py
eggs.py
我尝试通过添加 __init__.py
并执行 from Foo import *
将其转换为包,但它没有按照我的方式工作希望。
Could someone provide me with a good way of importing a whole directory of modules?
I have a structure like this:
/Foo
bar.py
spam.py
eggs.py
I tried just converting it to a package by adding __init__.py
and doing from Foo import *
but it didn't work the way I had hoped.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(22)
当
来自 . import *
还不够好,这是对ted的回答的改进。 具体来说,这种方法不需要使用__all__
。请注意,
module_name not in globals()
旨在避免重新导入已导入的模块,因为这可能会带来循环导入的风险。When
from . import *
isn't good enough, this is an improvement over the answer by ted. Specifically, the use of__all__
is not necessary with this approach.Note that
module_name not in globals()
is intended to avoid reimporting the module if it's already imported, as this can risk cyclic imports.这是迄今为止我发现的最好的方法:
This is the best way i've found so far:
Anurag Uniyal 答案以及建议的改进!
Anurag Uniyal answer with suggested improvements!
使用
importlib
是唯一的事情你必须添加的是Using
importlib
the only thing you've got to add is我想添加 Anurag Uniyal 的答案。
您可以使其变得更加简单并摆脱大量导入。
__init__.py 文件的内容:
I'd like to add to Anurag Uniyal's answer.
You can make it even simpler and get rid of a lot of the imports.
Contents of the __init__.py file:
我为此创建了一个模块,它不依赖于
__init__.py
(或任何其他辅助文件),并且使我只需键入以下两行:随意重用或贡献: http://gitlab.com/aurelien-lourot/importdir
I've created a module for that, which doesn't rely on
__init__.py
(or any other auxiliary file) and makes me type only the following two lines:Feel free to re-use or contribute: http://gitlab.com/aurelien-lourot/importdir
Anurag 的示例有一些更正:
Anurag's example with a couple of corrections:
查看您的
__init__.py
定义了__all__
。 模块 - 包 文档说See that your
__init__.py
defines__all__
. The modules - packages doc says查看标准库中的 pkgutil 模块。 只要目录中有
__init__.py
文件,它就可以让您完全执行您想要的操作。__init__.py
文件可以为空。Look at the pkgutil module from the standard library. It will let you do exactly what you want as long as you have an
__init__.py
file in the directory. The__init__.py
file can be empty.这是一个解决方案,使用它您不必写文件名。 只需将此代码片段添加到您的
__init__.py
源
Here is a solution, with which you do not have to write the file name. Just add this code snippet to your
__init__.py
Source
在 Python 3.9.5、Flask 2.2.2 中,没有一个解决方案对我有用,该模块是 cwd 下 2 级的目录。
这是我的解决方案:
None of the solutions was working for me in Python 3.9.5, Flask 2.2.2, the module being a directory 2 levels down the cwd.
This is my solution:
只需通过 importlib 导入它们并将它们添加到
__all__
(add
操作是可选的)在包的__init__.py
中递归。Just import them by importlib and add them to
__all__
(add
action is optional) in recurse in the__init__.py
of package.我有一个嵌套的目录结构,即主目录中有多个包含 python 模块的目录。
我将以下脚本添加到我的
__init__.py
文件中以导入所有模块可能不是实现此目的的最佳方法,但我无法让其他任何东西为我工作。
I had a nested directory structure i.e. I had multiple directories inside the main directory that contained the python modules.
I added the following script to my
__init__.py
file to import all the modulesProbably not the best way to achieve this, but I couldn't make anything else work for me.
列出当前文件夹中的所有 python (
.py
) 文件,并将它们作为__all__
变量放入__init__.py
中List all python (
.py
) files in the current folder and put them as__all__
variable in__init__.py
将
__all__
变量添加到__init__.py
中,其中包含:另请参阅 http://docs.python.org/tutorial/modules.html
Add the
__all__
Variable to__init__.py
containing:See also http://docs.python.org/tutorial/modules.html
2017 年更新:您可能想使用
importlib
代替。通过添加 __init__.py 使 Foo 目录成为一个包。 在
__init__.py
中添加:由于您希望它是动态的(这可能是也可能不是一个好主意),请使用 list dir 列出所有 py 文件并使用如下内容导入它们:
然后,从您的代码执行此操作:
您现在可以使用 etc 访问模块
。由于多种原因,
from Foo import *
不是一个好主意,包括名称冲突以及难以分析代码。Update in 2017: you probably want to use
importlib
instead.Make the Foo directory a package by adding an
__init__.py
. In that__init__.py
add:Since you want it dynamic (which may or may not be a good idea), list all py-files with list dir and import them with something like this:
Then, from your code do this:
You can now access the modules with
etc.
from Foo import *
is not a good idea for several reasons, including name clashes and making it hard to analyze the code.Python,包含一个目录下的所有文件:
对于那些无法让它工作、需要双手握住的新手。
创建一个文件夹 /home/el/foo 并在 /home/el/foo 下创建一个文件
main.py
将以下代码放入其中:创建一个目录
/home/el/foo/hellokitty
创建一个文件
__init__.py< /code> 下
/home/el/foo/hellokitty
并将此代码放在那里:制作两个 python文件:
/home/el/foo/hellokitty
下的
spam.py
和ham.py
在 spam.py 中定义一个函数:
在 ham.py 中定义一个函数:
运行它:
Python, include all files under a directory:
For newbies who just can't get it to work who need their hands held.
Make a folder /home/el/foo and make a file
main.py
under /home/el/foo Put this code in there:Make a directory
/home/el/foo/hellokitty
Make a file
__init__.py
under/home/el/foo/hellokitty
and put this code in there:Make two python files:
spam.py
andham.py
under/home/el/foo/hellokitty
Define a function inside spam.py:
Define a function inside ham.py:
Run it:
扩展 Mihail 的答案,我相信非黑客方式(例如,不直接处理文件路径)如下:
Foo/
__init__.py 文件>你会得到:
Expanding on Mihail's answer, I believe the non-hackish way (as in, not handling the file paths directly) is the following:
__init__.py
file underFoo/
You'll get:
我知道我正在更新一篇相当旧的帖子,我尝试使用 automodinit,但发现它的安装过程对于 python3 来说是损坏的。 因此,根据 Luca 的回答,我针对这个问题提出了一个更简单的答案(可能不适用于 .zip),所以我想我应该在这里分享它:
在
__init__.py
模块中yourpackage
:以及
yourpackage
下面的另一个包中:然后您将加载该包中放置的所有模块,如果您编写一个新模块,它将也会自动导入。 当然,这种东西要小心使用,能力越大责任越大。
I know I'm updating a quite old post, and I tried using
automodinit
, but found out it's setup process is broken for python3. So, based on Luca's answer, I came up with a simpler answer - which might not work with .zip - to this issue, so I figured I should share it here:within the
__init__.py
module fromyourpackage
:and within another package below
yourpackage
:Then you'll have all the modules that are placed within the package loaded, and if you write a new module, it'll be automagically imported as well. Of course, use that kind of things with care, with great powers comes great responsibilities.
我自己也厌倦了这个问题,所以我编写了一个名为 automodinit 的包来修复它。 您可以从 http://pypi.python.org/pypi/automodinit/ 获取它。
用法如下:
automodinit
包包含到setup.py
依赖项中。就是这样! 从现在开始导入模块会将 __all__ 设置为
模块中的 .py[co] 文件列表,还将导入每个文件
这些文件的数量就像您键入的一样:
因此“from M import *”的效果与“import M”完全匹配。
automodinit
很乐意从 ZIP 存档内部运行,因此是 ZIP 安全的。尼尔
I got tired of this problem myself, so I wrote a package called automodinit to fix it. You can get it from http://pypi.python.org/pypi/automodinit/.
Usage is like this:
automodinit
package into yoursetup.py
dependencies.That's it! From now on importing a module will set __all__ to
a list of .py[co] files in the module and will also import each
of those files as though you had typed:
Therefore the effect of "from M import *" matches exactly "import M".
automodinit
is happy running from inside ZIP archives and is therefore ZIP safe.Niall
我也遇到了这个问题,这是我的解决方案:
该函数创建一个名为 __init__.py 的文件(在提供的文件夹中),其中包含一个 __all__ 变量,该变量保存每个文件夹中的模块。
例如,我有一个名为
Test
的文件夹其中包含:
因此,在脚本中我希望将模块导入到我将编写的内容中:
这将从
Test
和Test 中的
现在将包含:__init__.py
文件导入所有内容I have also encountered this problem and this was my solution:
This function creates a file (in the provided folder) named
__init__.py
, which contains an__all__
variable that holds every module in the folder.For example, I have a folder named
Test
which contains:
So in the script I want the modules to be imported into I will write:
This will import everything from
Test
and the__init__.py
file inTest
will now contain: