在我的脚本和自定义模块中导入相同的内置模块是否有缺点?
我有一个脚本:导入我的自定义模块并导入内置的csv模块以打开csv文件并将任何必要的内容附加到列表中。
然后我在自定义模块中有一个方法,我在其中传递路径,文件名和列表并写入csv,但我必须再次导入csv模块(在我的模块中)。
我不明白当我导入csv模块两次时会发生什么,所以我想知道是否有一种更加统一的方式来做我正在做的事情,或者这是否正常。
答案 0 :(得分:3)
不,没有缺点。导入模块会两个事物:
sys.modules
。%20
)或模块对象(import modulename
)的属性。其他导入仅执行步骤2,因为模块已加载。
有关细节的详细信息,请参阅Python参考文档中的The import system:
from modulename import objectname
语句结合了两个操作;它搜索命名模块,然后将搜索结果绑定到本地范围内的名称。
答案 1 :(得分:2)
简短的回答是否定的,没有缺点。
话虽如此,了解进口的含义可能会有所帮助,特别是对于刚接触编程或来自不同语言背景的人。
我想你的代码看起来像这样:
# 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。
答案 2 :(得分:0)
据我所知,您可以在单独的文件(自定义模块)中导入相同的模块。 Python会跟踪已导入的模块,并知道如何解决第二次导入。