软件包中的Python导入模块

时间:2019-10-01 10:34:34

标签: python python-3.x package python-import

我目前有一个创建的模块,该模块具有许多功能。
它已经变得很大,所以我认为我应该将它包装成一个包,然后拆分功能以使其更易于管理。

如果要道歉,我只是在测试所有操作的方式,然后再道歉。
我创建了一个名为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
到目前为止一切都很好。


如果我想在subprocessenviron中引用foo.pybar.py,如何在其中引用?

如果在bar.py中有一个函数仅执行return subprocess.call('ls'),则会出现错误,提示 NameError:未定义名称'subprocess'。一定缺少我可以从上一级引用子流程的东西吗?大概,一旦我从中获得语法,就可以以类似的方式调用environ吗?

我可以看到的另一种选择是在import subprocessfoo.py中都包含bar.py,但是当我在多个文件中同时显示它时,这对我来说有点奇怪可以在更高级别使用一次,特别是如果我继续拥有大量文件而不是本例中只有2个文件的话。

2 个答案:

答案 0 :(得分:1)

TL; DR:

__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(同义)中,并将导入的名称绑定到当前名称空间中。每个Python模块都有(或“是”)它自己的名称空间(没有真正的“全局”名称空间)。 IOW,您必须在 each 模块中导入所需的内容,即,如果foo.py需要subprocess,则必须明确地导入它。

乍看之下这似乎有些乏味,但从长远来看,它确实对wrt /可维护性有所帮助-您只需要阅读模块顶部的导入内容(第08页:始终将所有导入内容放在模块开头即可) )以了解名称的来源。

此外,除了在python shell中(甚至是……)之外,您都不能在其他地方使用星号导入(也就是通配符导入,也称为from xxx import *)-这是维护定时炸弹。不仅因为您不知道每个名称的来源,还因为它是重新绑定已经导入的名称的肯定方法。想象一下,您的foo模块定义了函数“ func”。在某处有“ from foo import *; from bar import *”,然后在代码中稍后调用func。现在有人编辑bar.py并添加了一个(独特的)“ func”函数,突然调用失败,因为您没有调用预期的“ func”。现在,您可以进行调试了……实际示例通常比这复杂一些。

因此,如果您喜欢自己的精神理智,不要偷懒,也不要尝试变得聪明,只需做一个简单的显而易见的事情即可:在模块顶部显式导入您感兴趣的名称。 / p>

(在这里完成操作等)

答案 1 :(得分:-2)

您可以创建包含以下内容的modules.py

import subprocess
import os

然后在foo.py或您的任何文件中都拥有

from modules import *

您文件中的import语句是静态的,当您要添加一个所有人都可以访问的附加模块时,只需更新modules.py。