在 Python 中正确导入模块
如何设置模块导入以便每个模块都可以访问所有其他模块的对象?
我有一个中等大小的 Python 应用程序,其模块文件位于各个子目录中。 我创建了将这些子目录附加到 sys.path 的模块,并使用 import thisModule as tm 导入一组模块。 模块对象是用该限定来引用的。 然后,我使用 from moduleImports import *
将该模块导入到其他模块中。 现在的代码很草率,并且有一些这样的东西,而且通常是重复的。
首先,应用程序失败是因为未分配某些模块引用。 在单元测试时,同样的代码确实会运行。
其次,我担心我会导致递归模块导入出现问题。 导入 moduleImports 会导入 thisModule,后者会导入 moduleImports 。 。 。 。
这样做的正确方法是什么?
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.
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 . . . .
What is the right way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
“我有一个中等大小的 Python 应用程序,其模块文件位于各个子目录中。”
很好。 绝对确保每个目录都包含一个
__init__.py
文件,这样它就是一个包。“我创建了将这些子目录附加到
sys.path
的模块”错误。 使用
PYTHONPATH
或安装整个结构Lib/site-packages
。 不要动态更新sys.path
。 这是一件坏事。 难以管理和维护。“导入一组模块,使用
import thisModule as tm
。”没有意义。 也许您的结构中的每个模块都有一个
import thisModule as tm
。 这是典型的标准做法:仅导入您需要的模块,而不导入其他模块。“然后我使用
from moduleImports import *
”将该模块导入到其他模块中”不好。 不要一揽子导入一堆随机的东西。
每个模块都应该有一个较长的列表,列出它所需的具体内容。
明确的清单。 没有魔法。 没有对
sys.path
进行动态更改。我当前的项目有 100 个模块,十几个包。 每个模块只导入它需要的内容。 没有魔法。
"I have a medium size Python application with modules files in various subdirectories."
Good. Make absolutely sure that each directory include a
__init__.py
file, so that it's a package."I have created modules that append these subdirectories to
sys.path
"Bad. Use
PYTHONPATH
or install the whole structureLib/site-packages
. Don't updatesys.path
dynamically. It's a bad thing. Hard to manage and maintain."imports a group of modules, using
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."I then import that module into the others with
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.
Explicit list. No magic. No dynamic change to
sys.path
.My current project has 100's of modules, a dozen or so packages. Each module imports just what it needs. No magic.
一些提示
你可能已经分裂了
各种模块的功能。 如果
大多数时候你都正确地完成了
不会陷入循环进口
问题(例如,如果模块 a 依赖于
在 b 上,b 在 a 上,你可以做第三个
模块 c 删除此类循环
依赖性)。 作为最后的手段,在
导入 b 但在 b 中导入 a
需要 a 的点,例如内部
函数。
一旦功能正常
模块将它们分组在下面的包中
一个子目录并添加一个
__init__.py
文件以便您可以导入
包裹。 将此类包保存在
文件夹例如 lib,然后添加
到 sys.path 或设置 PYTHONPATH env
变量
from module import * 可能不会
是个好主意。 相反,导入任何东西
是需要的。 它可能是完全合格的。 它
啰嗦也没什么坏处。 例如
从 pakageA.moduleB 导入
CoolClass.
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
fileto 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
variable
from 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.
做到这一点的方法是避免魔法。 换句话说,如果您的模块需要另一个模块中的某些内容,则应该显式导入它。 您不应该依赖自动导入的内容。
正如 Python 的禅宗(
import this
)所言,显式优于隐式。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 会缓存每个模块并且不会重新加载已有的模块。
You won't get recursion on imports because Python caches each module and won't reload one it already has.