在 Python 中正确导入模块
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/896112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Properly importing modules in Python
提问by chernevik
How do I set up module imports so that each module can access the objects of all the others?
如何设置模块导入以便每个模块都可以访问所有其他模块的对象?
I have a medium size Python application with modules files in various subdirectories. I have created modules that append these subdirectories to sys.path
and imports a group of modules, using import thisModule as tm
. Module objects are referred to with that qualification. I then import that module into the others with from moduleImports import *
. The code is sloppy right now and has several of these things, which are often duplicative.
我有一个中等大小的 Python 应用程序,模块文件位于各个子目录中。我创建了将这些子目录附加到sys.path
并导入一组模块的模块,使用import thisModule as tm
. 模块对象是用该限定来引用的。然后我将该模块导入到其他模块中from moduleImports import *
。代码现在很草率,并且有几个这样的东西,这些东西通常是重复的。
First, the application is failing because some module references aren't assigned. This same code does run when unit tested.
首先,应用程序失败,因为未分配某些模块引用。相同的代码在单元测试时会运行。
Second, I'm worried that I'm causing a problem with recursive module imports. Importing moduleImports imports thisModule, which imports moduleImports . . . .
其次,我担心我会导致递归模块导入出现问题。导入 moduleImports 导入 thisModule,后者导入 moduleImports。. . .
What is the right way to do this?
这样做的正确方法是什么?
回答by S.Lott
"I have a medium size Python application with modules files in various subdirectories."
“我有一个中等大小的 Python 应用程序,模块文件位于各个子目录中。”
Good. Make absolutely sure that each directory include a __init__.py
file, so that it's a package.
好的。绝对确保每个目录都包含一个__init__.py
文件,以便它是一个包。
"I have created modules that append these subdirectories to sys.path
"
“我创建了将这些子目录附加到sys.path
”的模块
Bad. Use PYTHONPATH
or install the whole structure Lib/site-packages
. Don't update sys.path
dynamically. It's a bad thing. Hard to manage and maintain.
坏的。使用PYTHONPATH
或安装整体结构Lib/site-packages
。不要sys.path
动态更新。这是一件坏事。难以管理和维护。
"imports a group of modules, using import thisModule as tm
."
“导入一组模块,使用import thisModule as tm
.”
Doesn't make sense. Perhaps you have one import thisModule as tm
for each module in your structure. This is typical, standard practice: import just the modules you need, no others.
没有意义。也许您import thisModule as tm
的结构中的每个模块都有一个。这是典型的标准做法:只导入您需要的模块,不导入其他模块。
"I then import that module into the others with from moduleImports import *
"
“然后我将该模块导入到其他模块中from moduleImports import *
”
Bad. Don't blanket import a bunch of random stuff.
坏的。不要一揽子导入一堆随机的东西。
Each module should have a longish list of the specific things it needs.
每个模块都应该有一个很长的清单,列出它需要的特定东西。
import this
import that
import package.module
Explicit list. No magic. No dynamic change to sys.path
.
显式列表。没有魔法。没有动态变化sys.path
。
My current project has 100's of modules, a dozen or so packages. Each module imports just what it needs. No magic.
我目前的项目有 100 个模块,十几个包。每个模块只导入它需要的东西。没有魔法。
回答by Anurag Uniyal
Few pointers
少指点
You may have already split functionality in various module. If correctly done most of the time you will not fall into circular import problems (e.g. if module a depends on b and b on a you can make a third module c to remove such circular dependency). As last resort, in a import b but in b import a at the point where a is needed e.g. inside function.
Once functionality is properly in modules group them in packages under a subdir and add a
__init__.py
file to it so that you can import the package. Keep such pakages in a folder e.g. lib and then either add to sys.path or set PYTHONPATH env variablefrom module import * may not be good idea. Instead, import whatever is needed. It may be fully qualified. It doesn't hurt to be verbose. e.g. from pakageA.moduleB import CoolClass.
您可能已经在各个模块中拆分了功能。如果大部分时间都正确完成,您将不会陷入循环导入问题(例如,如果模块 a 依赖于 b 并且 b 依赖于 a,您可以创建第三个模块 c 以消除这种循环依赖)。作为最后的手段,在 a 中导入 b 但在 b 中导入 a 在需要 a 的地方,例如在函数内部。
一旦模块中的功能正确,将它们分组到子目录下的包中,并向其中添加
__init__.py
文件,以便您可以导入包。将这些包保存在一个文件夹中,例如 lib,然后添加到 sys.path 或设置 PYTHONPATH 环境变量from module import * 可能不是个好主意。相反,导入任何需要的东西。它可能是完全合格的。冗长并没有什么坏处。例如从 pakageA.moduleB 导入 CoolClass。
回答by Daniel Roseman
The way to do this is to avoid magic. In other words, if your module requires something from another module, it should import it explicitly. You shouldn't rely on things being imported automatically.
这样做的方法是避免魔法。换句话说,如果你的模块需要来自另一个模块的东西,它应该明确地导入它。你不应该依赖自动导入的东西。
As the Zen of Python (import this
) has it, explicit is better than implicit.
正如 Python 之禅 ( import this
) 所言,显式优于隐式。
回答by SpliFF
You won't get recursion on imports because Python caches each module and won't reload one it already has.
您不会对导入进行递归,因为 Python 会缓存每个模块并且不会重新加载它已有的模块。