Python模块:如何防止导入新模块调用的模块
Posted
技术标签:
【中文标题】Python模块:如何防止导入新模块调用的模块【英文标题】:Python module: how to prevent importing modules called by the new module 【发布时间】:2013-12-13 01:42:45 【问题描述】:我是Python
的新手,我正在创建一个模块来重用一些代码。
我的模块(impy.py
)看起来像这样(到目前为止它只有一个功能)...
import numpy as np
def read_image(fname):
....
并且存储在以下目录中:
custom_modules/
__init.py__
impy.py
如您所见,它使用模块 numpy.问题是当我从另一个脚本导入它时,像这样......
import custom_modules.impy as im
然后我输入im.
,我不仅可以选择调用函数read_image()
,还可以调用模块np
。
我怎样才能使它只可用我在我的模块中编写的函数,而不是我的模块正在调用的模块(在这种情况下为 numpy)?
非常感谢您的帮助。
【问题讨论】:
在我看来这很正常,因为import
使模块属于模块的内存空间。那么,“我可以选择致电(...)”是什么意思?这是您的 IDE 的提议吗?在这种情况下,
@Joël 是的,这是 IDE (Spyder) 的提议。但无论如何我认为用户能够通过我的模块调用 numpy 是不好的,它应该是防止这种情况的一种方式......
好吧,我想说这是 IDE 的问题,而不是 Python 的问题,它为您提供了对所有可用对象的引用。
我不认为...我认为这应该是防止这种情况发生的一种方式...
是的,我在 Idle 中看到了这一点,所以我理解您对模块导入和模块属性/类/函数之间有些混淆的担忧,请参阅我的回答。
【参考方案1】:
如果你真的想隐藏它,那么我建议创建一个新目录,使你的结构看起来像这样:
custom_modules/
__init__.py
impy/
__init__.py
impy.py
并让新的impy/__init__.py
包含
from impy import read_image
这样,您可以控制 custom_modules.impy
命名空间中的内容。
【讨论】:
【参考方案2】:我有一个提议,或许可以回答以下问题:“我不想将类/模块属性与类/模块导入混淆”。因为,Idle 还建议访问类或模块中的导入模块。
这只是采用编码人员通常不想访问且 IDE 不建议使用的常规名称:以下划线开头的名称。这也称为“弱«内部使用»指标”,如PEP 8 / Naming styles 中所述。
class C(object):
import numpy as _np # <-- here
def __init__(self):
# whatever we need
def do(self, arg):
# something useful
现在,在空闲时,自动补全只会提出do
函数;不建议导入模块。
顺便说一句,您应该更改问题的标题:您不想避免导入导入的模块(这会使它们无法使用),因此应该是“如何防止 IDE 显示导入的模块导入的模块”或类似的东西。
【讨论】:
我同意你最后的说法,问题标题应该更新【参考方案3】:你可以在你的函数中导入 numpy
def read_image(fname):
import numpy as np
....
使其在本地可用于read_image
代码,但不可全局使用。
警告,但这可能会导致性能下降(因为每次运行代码时都会导入numpy
,而不是在初始导入时只导入一次) - 特别是如果您多次运行read_image
。
【讨论】:
是的,这就是问题所在。我必须多次运行该函数,而且它被其他函数调用...这就是为什么我想要另一个解决方案...谢谢! 导入只会在第一次完成,无论是否懒惰。导入 sys.modules 中已有的模块只会绑定名称,不会再次运行模块中的代码。 如果模块中唯一可用的函数需要numpy
,则没有兴趣在函数中隐藏导入,因为无论如何都会完成导入。更糟糕的是,如果要多次调用该函数,即使成本不高,也会多次检查导入。
@betelgeuse 为了提供更完整的答案,了解 为什么 周围有 numpy 可能会很有用...
@danodonovan,因为当我调用该模块的函数时,IDE 给我的选项中看不到什么以上是关于Python模块:如何防止导入新模块调用的模块的主要内容,如果未能解决你的问题,请参考以下文章