![](/img/trans.png)
[英]Organizing package Python - importing modules that are used with the package
[英]Python Importing modules in a package
我目前有一个我创建的具有许多功能的模块。
它变得相当大,所以我想我应该把它变成一个 package 并将功能分开以使其更易于管理。
在我真正做到这一点之前,我只是在测试这一切是如何工作的,如果它看起来有点脆弱,我深表歉意。
我创建了一个名为pack_test
的文件夹,其中有:
__init__.py
foo.py
bar.py
__init__.py
包含:
__all__ = ['foo', 'bar']
from . import *
import subprocess
from os import environ
在控制台中,我可以编写import pack_test as pt
这很好,没有错误。
pt.
两个标签显示我可以在其中看到pt.bar
、 pt.environ
、 pt.foo
和pt.subprocess
。
到目前为止一切都很好。
如果我想在foo.py
或bar.py
中引用subprocess
或environ
,我该怎么做呢?
如果在bar.py
我有一个 function 它只是return subprocess.call('ls')
它错误说NameError: name 'subprocess' is not defined 。 一定有我遗漏的东西使我能够从上面的级别引用子流程? 据推测,一旦我可以从中获得语法,我也可以以类似的方式调用 environ 吗?
我可以看到的另一种选择是在foo.py
和bar.py
中都有import subprocess
subprocess ,但是当我可以在更高级别一次使用它时,让它出现在多个文件中对我来说似乎有点奇怪,特别是如果我继续拥有大量文件而不是本示例中的 2 个文件。
TL;博士:
__init__.py
:
import foo
import bar
__all__ = ["foo", "bar"]
foo.py
:
import subprocess
from os import environ
# your code here
bar.py
import subprocess
from os import environ
# your code here
一定有我遗漏的东西使我能够从上面的级别引用子流程?
不,这是预期的行为。
import
加载一个模块(如果还没有),将其缓存在sys.modules
(idem) 中,并将导入的名称绑定到当前命名空间中。 每个 Python 模块都有(或“是”)它自己的命名空间(没有真正的“全局”命名空间)。 IOW,你必须在每个模块中导入你需要的东西,即如果 foo.py 需要subprocess
,它必须明确地导入它。
起初这似乎有点乏味,但从长远来看,它确实有助于 wrt/可维护性 - 您只需阅读模块顶部的导入(pep 08:始终将所有导入放在模块的开头)即可知道名字的来源。
此外,您不应在 python shell (即使那样......)之外的任何地方使用星号导入(又名通配符导入又名from xxx import *
) - 这是一个维护定时炸弹。 不仅因为您不知道每个名称的来源,还因为这是重新绑定已导入名称的可靠方法。 想象一下,您的 foo 模块定义了 function “func”。 某处有“from foo import *; from bar import *”,然后在代码中调用 func。 现在有人编辑 bar.py 并添加了一个(不同的)“func”function,突然你调用失败了,因为你没有调用预期的“func”。 现在享受调试吧……现实生活中的例子通常比这复杂一点。
因此,如果您希望自己的头脑清醒,不要偷懒,也不要试图变得聪明,只需做简单显而易见的事情:在模块顶部显式导入您感兴趣的名称。
(在这里,做过等)
您可以创建 modules.py 包含
import subprocess
import os
然后在 foo.py 或您的任何文件中。
from modules import *
然后,您文件中的导入语句为 static,当您想添加一个可供所有人访问的附加模块时,只需更新 modules.py。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.