2010-01-08 150 views
21

在編寫python模塊時,有沒有辦法阻止它被客戶端代碼導入兩次?就像c/C++頭文件一樣:如何防止兩次導入模塊?

#ifndef XXX 
#define XXX 
... 
#endif 

非常感謝!

回答

30

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

請注意,'重載()'不會修復了舊模塊的任何引用,所以實際上不是那麼有用。 – 2010-01-08 17:56:07

+0

這是一個重要的觀點。謝謝。 – 2010-01-08 18:01:01

+1

參考資料:http://docs.python.org/tutorial/modules.html#more-on-modules。 http://docs.python.org/reference/simple_stmts.html#the-import-statement – 2010-01-08 20:39:30

13

導入緩存,只能運行一次。其他導入只會花費sys.modules中的查找時間。

9

在其他的答案中指定,的Python遇到第二個import語句它時,一般不重新加載的模塊。相反,它會從sys.modules返回其緩存版本,而不執行任何代碼。

但是有幾個陷阱值得注意:

  • 導入主模塊作爲一個普通的模塊有效地創建不同的名字在同一模塊的兩個實例。

    這是因爲程序啓動期間the main module is set up with the name __main__。因此,將其作爲普通模塊導入時,Pythonsys.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.pya.py一個import語句(import a )。
    執行/tmp/a.py結果如下輸出:

    [email protected]:/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. 稍有不同的import語句使用不同的條目sys.path導致同一模塊。
    2. 嘗試在前一個模塊中途失敗後再次導入模塊。
+2

這實際上幫助我解決了這個問題,其他答案並不完整。 – Tapuzi 2016-06-26 16:13:02

+1

這就是我要找的。謝謝。 – bfrguci 2016-08-01 23:15:44