我目前有一个创建的模块,该模块具有许多功能。
它已经变得很大,所以我认为我应该将它包装成一个包,然后拆分功能以使其更易于管理。
如果要道歉,我只是在测试所有操作的方式,然后再道歉。
我创建了一个名为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
。
到目前为止一切都很好。
如果我想在subprocess
或environ
中引用foo.py
或bar.py
,如何在其中引用?
如果在bar.py
中有一个函数仅执行return subprocess.call('ls')
,则会出现错误,提示 NameError:未定义名称'subprocess'。一定缺少我可以从上一级引用子流程的东西吗?大概,一旦我从中获得语法,就可以以类似的方式调用environ吗?
我可以看到的另一种选择是在import subprocess
和foo.py
中都包含bar.py
,但是当我在多个文件中同时显示它时,这对我来说有点奇怪可以在更高级别使用一次,特别是如果我继续拥有大量文件而不是本例中只有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。