我有script1.py
,其中有
from itertools import izip_longest, islice
在script1.py
中的某个地方使用了islice
。
我还有另一个脚本script2.py
,该脚本需要在script1.py
中自动执行,因为script1
的输出文件是script2
的输入文件。问题是,script2
也需要使用islice
。有没有一种方法可以使用它而无需再次在islice
中导入script2
?
答案 0 :(得分:3)
在islice
中使用script2
的Python方法是
from itertools import islice
Python中的导入机制非常聪明。导入模块不会每次都自动加载模块。第一步始终是检查模块是否已经在sys.modules
中。如果是(如您的情况),则将适当的现有引用绑定到名称空间中的名称。
让我们看一个具体的示例,其中包含以下两个模块:
mod1.py
from itertools import izip_longest, islice
from mod2 import some_function
# code that uses islice and some_function
mod2.py
from itertools import islice
def some_function():
# do the thing
如果您运行mod1
,则会发生以下(已编辑)事件序列:
sys.modules['mod1']
或sys.modules['__main__']
下注册/缓存它。mod1.py
中的代码。itertools
是否在sys.modules
中:不是
itertools
并将其加载到sys.modules['itertools']
izip_longest
和islice
添加到不完整的mod1
中的全局命名空间中mod2
是否在sys.modules
中:不是
mod2
并创建一个空的sys.modules['mod2']
mod2.py
中的代码。itertools
中是否有sys.modules
:islice
添加到不完整的mod2
中的全局命名空间中。这基本上等同于此时进行islice = sys.modules['itertools'].islice
。这里什么都没装。def
语句以创建一个函数对象,并将其添加到名称为mod2
的{{1}}全局命名空间中。some_func
现在已完全加载mod2
中的其余代码如您所见,虽然可以说mod1
模块在技术上被导入了两次,但仅被加载了一次。第二次,名称itertools
绑定到本地名称。
您可以在这里阅读有关整个过程的官方文档:https://docs.python.org/2/reference/simple_stmts.html#the-import-statement。从至少一个版本2.0:https://docs.python.org/2.0/ref/import.html开始,此事件序列在一个实现中或另一个实现中都已存在。您可能还想在这里https://docs.python.org/2/tutorial/modules.html阅读更多有关模块工作原理的信息。通常,我发现官方文档可能是Stack Overflow之外最好的Python老师。
要记住的另一件事是模块不共享名称空间。模块内的全局变量只是该特定模块对象的属性。但是,您可能会执行以下操作:
mod2.py
islice
mod1.py
from itertools import islice
def some_function(): pass
这样,您只有一次明确导入import mod2
#use mod2.some_function and mod2.islice as attributes of mod2
。但是我不认为这是一种非常pythonic的方法。 Python的主要原则之一是“显式胜于隐式”,可读性比简洁性更重要。当您使用islice
时,对读者的暗示是mod2.islice
定义的函数版本不同于内置函数。
顺便说一句,考虑尽快迁移到Python 3.6+。有许多改进和新功能。不再支持Python 2.x,许多流行的第三方库(例如numpy)将在即将发布的版本中完全放弃对Python 2的支持。
答案 1 :(得分:2)
您可以在这里执行的是从script1导入*
,该脚本也将包括其所有导入。像这样:
# in script2.py
from script1 import *
这样,您只需要执行一次导入。这是你的意思吗?