繁体   English   中英

Python 在 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.barpt.environpt.foopt.subprocess
到目前为止一切都很好。


如果我想在foo.pybar.py中引用subprocessenviron ,我该怎么做呢?

如果在bar.py我有一个 function 它只是return subprocess.call('ls')它错误说NameError: name 'subprocess' is not defined 一定有我遗漏的东西使我能够从上面的级别引用子流程? 据推测,一旦我可以从中获得语法,我也可以以类似的方式调用 environ 吗?

我可以看到的另一种选择是在foo.pybar.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM