2013-02-11 47 views
0

我有一個Django項目。這個Django項目的一部分是一個報告模塊,它在所有INSTALLED_APPS內搜索報告目錄,這與管理界面的自動發現機制非常相似。兩次導入的模塊導致其內部對象的娛樂

該模塊有一個註冊類的小型註冊類。在一個非常簡單的方式,它看起來是這樣的:

def autodiscover(): 
    """ 
    Searches for reports module in all INSTALLED_APPS 
    """ 

    global REPORTSLOADING 
    if REPORTSLOADING: 
     return 
    REPORTSLOADING = True 

    import imp 
    from django.conf import settings 

    for app in settings.INSTALLED_APPS: 
     try: 
      app_path = import_module(app).__path__ 
     except AttributeError: 
      continue 

     try: 
      imp.find_module('reports', app_path) 
     except ImportError: 
      continue 

     import_module("%s.reports" % app) 
    REPORTSLOADING = False 

class ReportsRegistery(object): 
     ..... 

registery = ReportsRegistery() 

如果任何INSTALLED_APPS的需要註冊一個報告類,我們需要內部reports/__init__.py行:

import reports 
reports.registery.register(SomeReportClass) 

和主要的網址內。 PY我會做:

import reports 
reports.autodiscover() 


urlpatterns = patterns('', 
.... 

(r'', include(reports.registery.urls)), 
) 

現在我決定爲它創建一個可插拔的Django應用程序,放在同一代碼在包的__init__.py。我面臨的問題是具有新結構的報告模塊會被導入兩次,從而導致「註冊」對象的重新創建。所以,沒有真正註冊的網址。它從urls.py中導入一次(如預期),另一次由autodiscover啓動。我已通過以下驗證:

print hex(id(registery)) 

發現它返回了2個不同的值。

我認爲報告包將被導入一次,就像它只是一個模塊一樣。

如何防止它被加載兩次?或者我如何確保我們只有一個ReportsRegistery實例可以使用?

+0

導入模塊這不是如何導入在Python工程;再次導入模塊只是返回現有的模塊對象。你可以在sys.modules結構中獲得兩次模塊的唯一方法是通過一個符號鏈接('foo.py'指向'bar.py')導入兩個不同的名稱,或者模塊被用作主python腳本('python bar.py'),然後再次導入('import bar');在這種情況下,模塊同時存在「bar」和「__main__」。 – 2013-02-11 16:06:44

+2

你可以自由地忽略一個迂腐的挑剔:它被拼寫成'註冊表'。:-P – 2013-02-11 16:09:01

+0

我認爲它是用不同的名稱導入的,爲什麼我檢查了導入。根據我所做的檢查,它只輸入了兩次,名字相同但對象不同。並感謝迂腐檢查:) – thelinuxer 2013-02-11 16:22:09

回答

0

Django導入模塊兩次並不罕見。有兩個原因:

  1. 經典的Django項目佈局鼓勵你在兩個不同的位置有路徑上的工作目錄兩次。這意味着您可以輸入project.moduleapp.project.module,這會混淆進口機器。

  2. settings.py文件實際上導入了兩次。

修正:

  1. 仔細檢查所有的進口使用路徑相同的樣式。

  2. 不要從settings.py

+0

根據我的檢查,該模塊不導入不同的名稱。有沒有辦法打印什麼是導入模塊,以確保? – thelinuxer 2013-02-11 16:22:56

+0

真的嗎?有和沒有嵌套的命名空間?啊。 – 2013-02-11 16:23:27

+0

我現在更改爲導入到「projectname.reports」,它工作正常。仍然不知道爲什麼「導入報告」本身不起作用! – thelinuxer 2013-02-11 16:29:44