我可以在脚本和自定义模块中两次导入内置模块

时间:2015-05-20 20:49:04

标签: python python-module

在我的脚本和自定义模块中导入相同的内置模块是否有缺点?

我有一个脚本:导入我的自定义模块并导入内置的csv模块以打开csv文件并将任何必要的内容附加到列表中。

然后我在自定义模块中有一个方法,我在其中传递路径,文件名和列表并写入csv,但我必须再次导入csv模块(在我的模块中)。

我不明白当我导入csv模块两次时会发生什么,所以我想知道是否有一种更加统一的方式来做我正在做的事情,或者这是否正常。

3 个答案:

答案 0 :(得分:3)

不,没有缺点。导入模块会两个事物:

  1. 如果尚未在内存中,请加载模块,将生成的对象存储在sys.modules
  2. 将名称绑定到模块对象(%20)或模块对象(import modulename)的属性。
  3. 其他导入仅执行步骤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会跟踪已导入的模块,并知道如何解决第二次导入。