[英]Web.py NameError When Importing Module in Module
我正在python 2.7.3上使用web.py創建一個Web應用程序。 我具有以下文件夾結構:
start_app.py
/app
__init__.py
/models
__init__.py
ActionModel.py
AreaModel.py
/controllers
__init__.py
world.py
/views
每當我使用python start_app.py
重新啟動應用程序並訪問world/surrounding
,都會出現以下錯誤
<type 'exceptions.ImportError'> at /world/surrounding
cannot import name AreaModel
Python /home/dev/app/models/ActionModel.py in <module>, line 13
Web GET http://localhost:5000/world/surrounding
第13行很簡單: from app.models import AreaModel
但是我不明白為什么python在這里抱怨。
如果我評論此導入行,則可以正常運行。 但是,如果我調用其他URL,例如world/view
,則會收到未定義AreaModel的錯誤。 一旦取消注釋,在所有情況下(即/ surrounding和/ view)它都可以正常工作。
我懷疑這與我在“圈子中導入”有關,即world.py導入AreaModel,AreaModel導入ActionModel,而ActionModel導入AreaModel。 我懷疑這是做事的“ pythonic方式”,甚至是“ MVC方式”,所以我非常感謝您的啟發給我如何正確地做這件事。
注意:app不在我的PYTHONPATH中,但我認為這里不需要它,因為start_app.py位於頂層目錄中,根據此,所有模塊都應該可用。
基本上,歸結為:我需要控制器和模型中的模型功能。 “導入圈子”是一種好習慣嗎? 還是有更好的方法來做到這一點? 另外,這個問題是與python一般有關還是與web.py有關?
更新:添加了init .py文件,我安裝了它們,但是沒有包含在原始問題中。 抱歉
更新: ActionModel.py包括(其中包括)一個名為BaseAction的類和一些函數,這些函數根據我們正在處理的Action類型來返回BaseAction的實例或子類。 使用例如ActionModel.get_by_id()
調用它們
@ matthew-trevor:您是否在a)中建議將這些函數get_by_id()
移到ActionModel類中?
#actionmodel.py
class ActionModel(object):
def __init__(arg1, arg2, area_class):
self.area = area_class()
def get_by_id(self, id):
return BaseAction(id)
class BaseAction(object):
def __init__(id):
pass
我看不出這應該如何解決我的進口問題。
眼前的問題
您不能從文件夾導入,但是可以從軟件包導入。 您可以通過將__init__.py
文件添加到其中來將任何文件夾變成一個包:
start_app.py
/app
__init__.py
/models
__init__.py
ActionModel.py
AreaModel.py
/controllers
__init__.py
world.py
/views
__init__.py
我猜想ActionModel.py
包含一個同名的類。 如果是這樣,我建議將文件重命名為actionmodel.py
以將其與類區分開。
循環進口
“導入圈子”是一種好習慣嗎? 還是有更好的方法來做到這一點?
這不僅是一種不好的做法,而且還是行不通的。 有兩種解決方法,這主要取決於您要執行的操作:
一種。 在AreaModel
,導入ActionModel
模塊,然后通過屬性查找引用要在其中使用的任何內容,反之亦然:
# areamodel.py
import actionmodel
def foo():
action = actionmodel.ActionModel(...)
只要引用在類或函數定義內部,它就只會在運行時發生,而不會在導入期間發生,因此避免了循環引用。
b。 將models
轉換為模塊,然后將ActionModel
和AreaModel
代碼放入其中。
C。 將ActionModel
和AreaModel
的共享代碼/功能移動到它們都AreaModel
導入的基本模塊中。
d。 讓你的ActionModel
類(或其他)接受一個類作為輸入,然后通過AreaModel
到它world.py
(同上,用於AreaModel
)。 這樣, ActionModel
不需要包含對AreaModel
的引用, AreaModel
需要知道如何處理它:
# actionmodel.py
class ActionModel(object):
def __init__(arg1, arg2, area_class):
self.area = area_class()
# areamodel.py
class AreaModel(object):
def __init__(action_class):
self.action = action_class()
# world.py
from actionmodel import ActionModel
from areamodel import AreaModel
action = ActionModel('foo', 'bar', AreaModel)
area = AreaModel(ActionModel)
這稱為對象合成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.