我可以在脚本和自定义模块中两次导入内置模块吗
Can I import a built-in module twice in both my script and custom module
在我的脚本和自定义模块中导入相同的内置模块是否有缺点?
我有一个脚本:导入我的自定义模块并导入内置的 csv 模块以打开 csv 文件并将任何必要的内容附加到列表中。
然后我在我的自定义模块中有一个方法,我在其中传递路径、文件名和列表并写入一个 csv,但我必须再次导入 csv 模块(在我的模块中)。
我不明白当我两次导入 csv 模块时会发生什么,所以我想知道是否有更统一的方式来做我正在做的事情,或者这是否可以。
不,没有缺点。导入模块会做 两件事:
- 如果不在内存中,加载模块,将生成的对象存储在
sys.modules
。
- 将名称绑定到模块对象 (
import modulename
) 或模块对象的属性 (from modulename import objectname
)。
额外的导入只执行第 2 步,因为模块已经加载。
请参阅 Python 参考文档中的 The import system 了解具体细节:
The import
statement combines two operations; it searches for the named module, then it binds the results of that search to a name in the local scope.
据我所知,您可以在单独的文件(自定义模块)中导入相同的模块。 Python 跟踪已导入的模块并知道如何解决第二次导入。
简短的回答是否定的,没有缺点。
话虽如此,理解导入的含义可能会有所帮助,特别是对于编程新手或来自不同语言背景的人。
我想你的代码看起来像这样:
# my_module.py
import os
import csv
def bar(path, filename, list):
full_path = os.path.join(path, filename)
with open(full_path, 'w') as f:
csv_writer = csv.writer
csv_writer.writerows(list)
和
# my_script.py
import csv
import my_module
def foo(path):
contents = []
with open(path, 'r') as f:
csv_reader = csv.reader(f)
for row in csv_reader:
contents.append(row)
作为高级概述,当您以这种方式导入时,Python 确定模块是否已导入。如果不是,则它会搜索 Python 路径以确定导入模块在文件系统中的位置,然后将导入模块的代码加载到内存中并执行它。解释器获取在导入模块执行期间创建的所有对象,并使它们成为解释器创建的新模块对象的属性。然后解释器将这个模块对象存储到一个类似字典的结构中,该结构将模块名称映射到模块对象。最后,解释器将导入模块的名称带入导入模块的范围。
这会产生一些有趣的结果。例如,这意味着您可以简单地使用 my_module.csv
来访问 my_script.py 中的 csv 模块。这也意味着在两者中导入 csv 是微不足道的,并且可能是您可以做的最清楚的事情。
一个非常有趣的结果是,如果在导入期间执行的任何语句有任何副作用,这些副作用只会在解释器首次加载模块时发生。例如,假设您有两个模块 a.py 和 b.py,代码如下:
# a.py
print('hello world')
# b.py
print('goodbye world')
import a
如果你 运行 import a
后跟 import b
那么你会看到
>>> import a
hello world
>>> import b
goodbye world
>>>
但是,如果您以相反的顺序导入,您会得到:
>>> import b
goodbye world
hello world
>>> import a
>>>
无论如何,我想我已经说得够多了,我希望在提供一些背景知识的同时我已经充分回答了这个问题。如果这很有趣,我会推荐 Allison Kaptur's PyCon 2014 talk about import。
在我的脚本和自定义模块中导入相同的内置模块是否有缺点?
我有一个脚本:导入我的自定义模块并导入内置的 csv 模块以打开 csv 文件并将任何必要的内容附加到列表中。
然后我在我的自定义模块中有一个方法,我在其中传递路径、文件名和列表并写入一个 csv,但我必须再次导入 csv 模块(在我的模块中)。
我不明白当我两次导入 csv 模块时会发生什么,所以我想知道是否有更统一的方式来做我正在做的事情,或者这是否可以。
不,没有缺点。导入模块会做 两件事:
- 如果不在内存中,加载模块,将生成的对象存储在
sys.modules
。 - 将名称绑定到模块对象 (
import modulename
) 或模块对象的属性 (from modulename import objectname
)。
额外的导入只执行第 2 步,因为模块已经加载。
请参阅 Python 参考文档中的 The import system 了解具体细节:
The
import
statement combines two operations; it searches for the named module, then it binds the results of that search to a name in the local scope.
据我所知,您可以在单独的文件(自定义模块)中导入相同的模块。 Python 跟踪已导入的模块并知道如何解决第二次导入。
简短的回答是否定的,没有缺点。
话虽如此,理解导入的含义可能会有所帮助,特别是对于编程新手或来自不同语言背景的人。
我想你的代码看起来像这样:
# my_module.py
import os
import csv
def bar(path, filename, list):
full_path = os.path.join(path, filename)
with open(full_path, 'w') as f:
csv_writer = csv.writer
csv_writer.writerows(list)
和
# my_script.py
import csv
import my_module
def foo(path):
contents = []
with open(path, 'r') as f:
csv_reader = csv.reader(f)
for row in csv_reader:
contents.append(row)
作为高级概述,当您以这种方式导入时,Python 确定模块是否已导入。如果不是,则它会搜索 Python 路径以确定导入模块在文件系统中的位置,然后将导入模块的代码加载到内存中并执行它。解释器获取在导入模块执行期间创建的所有对象,并使它们成为解释器创建的新模块对象的属性。然后解释器将这个模块对象存储到一个类似字典的结构中,该结构将模块名称映射到模块对象。最后,解释器将导入模块的名称带入导入模块的范围。
这会产生一些有趣的结果。例如,这意味着您可以简单地使用 my_module.csv
来访问 my_script.py 中的 csv 模块。这也意味着在两者中导入 csv 是微不足道的,并且可能是您可以做的最清楚的事情。
一个非常有趣的结果是,如果在导入期间执行的任何语句有任何副作用,这些副作用只会在解释器首次加载模块时发生。例如,假设您有两个模块 a.py 和 b.py,代码如下:
# a.py
print('hello world')
# b.py
print('goodbye world')
import a
如果你 运行 import a
后跟 import b
那么你会看到
>>> import a
hello world
>>> import b
goodbye world
>>>
但是,如果您以相反的顺序导入,您会得到:
>>> import b
goodbye world
hello world
>>> import a
>>>
无论如何,我想我已经说得够多了,我希望在提供一些背景知识的同时我已经充分回答了这个问题。如果这很有趣,我会推荐 Allison Kaptur's PyCon 2014 talk about import。