我有一個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實例可以使用?
導入模塊這不是如何導入在Python工程;再次導入模塊只是返回現有的模塊對象。你可以在sys.modules結構中獲得兩次模塊的唯一方法是通過一個符號鏈接('foo.py'指向'bar.py')導入兩個不同的名稱,或者模塊被用作主python腳本('python bar.py'),然後再次導入('import bar');在這種情況下,模塊同時存在「bar」和「__main__」。 – 2013-02-11 16:06:44
你可以自由地忽略一個迂腐的挑剔:它被拼寫成'註冊表'。:-P – 2013-02-11 16:09:01
我認爲它是用不同的名稱導入的,爲什麼我檢查了導入。根據我所做的檢查,它只輸入了兩次,名字相同但對象不同。並感謝迂腐檢查:) – thelinuxer 2013-02-11 16:22:09