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

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 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.


    简短的回答是不,没有负面影响。

    尽管如此,理解导入的含义可能会有所帮助,特别是对于编程新手或来自不同语言背景的人。

    我想您的代码看起来是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 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)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 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,代码如下:

    1
    2
    3
    4
    5
    6
    # a.py
    print('hello world')

    # b.py
    print('goodbye world')
    import a

    如果运行import a,然后运行import b,那么您将看到

    1
    2
    3
    4
    5
    >>> import a
    hello world
    >>> import b
    goodbye world
    >>>

    但是,如果按相反的顺序导入,则会得到:

    1
    2
    3
    4
    5
    >>> import b
    goodbye world
    hello world
    >>> import a
    >>>

    不管怎样,我觉得我已经说得够多了,我希望我在给出一些背景的同时,能充分回答这个问题。如果这有意思的话,我建议Allison Kaptur的Pycon 2014谈论进口。


    据我所知,您可以在单独的文件(自定义模块)中导入相同的模块。python跟踪已经导入的模块,并知道如何解决第二次导入。