如何防止模块导入两次?

时间:2010-01-08 17:49:45

标签: python import module

编写python模块时,有没有办法阻止它被客户端代码导入两次?就像c / c ++头文件一样:

#ifndef XXX
#define XXX
...
#endif

非常感谢!

3 个答案:

答案 0 :(得分:38)

Python模块不会多次导入。只运行两次导入将不会重新加载模块。如果要重新加载,则必须使用reload语句。这是一个演示

foo.py是一个单行

的模块
print "I am being imported"

这是多次导入尝试的屏幕记录。

   >>> import foo
   Hello, I am being imported
   >>> import foo # Will not print the statement
   >>> reload(foo) # Will print it again
   Hello, I am being imported

答案 1 :(得分:17)

导入缓存,只运行一次。其他导入仅花费sys.modules中的查找时间。

答案 2 :(得分:13)

如其他答案所述, Python 在遇到第二个导入语句时通常不会重新加载模块。相反,它从sys.modules返回其缓存版本,而不执行任何代码。

然而,有几个值得注意的陷阱:

  • 将主模块作为普通模块导入,可以有效地创建不同名称下同一模块的两个实例。

    这是因为在程序启动期间the main module is set up with the name __main__。因此,当将其作为普通模块导入时, Python 不会在sys.modules中检测到它并再次导入它,但第二次使用其正确的名称。

    考虑文件 /tmp/a.py ,其中包含以下内容:

    # /tmp/a.py
    import sys
    
    print "%s executing as %s, recognized as %s in sys.modules" % (__file__, __name__, sys.modules[__name__])
    import b
    

    另一个文件 /tmp/b.py 只有一个 a.py import a)的导入语句。
    执行 /tmp/a.py 会产生以下输出:

    root@machine:/tmp$ python a.py
    a.py executing as __main__, recognized as <module '__main__' from 'a.py'> in sys.modules
    /tmp/a.pyc executing as a, recognized as <module 'a' from '/tmp/a.pyc'> in sys.modules
    

    因此,最好保持主模块的最小化,并将其大部分功能导出到外部模块,如here所述。

  • This answer指定了两种可能的方案:

    1. 使用sys.path中不同条目导致相同模块的导入语句略有不同。
    2. 尝试在上一次模块失败后再次导入模块。