2014-01-29 76 views
0

我正在使用python 2.7.3上的web.py創建一個web應用程序。 我有以下文件夾結構:當在模塊中導入模塊時,Web.py NameError

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在這裏抱怨。

如果我評論這個導入行,它運行良好。不過,如果我撥打其他網址,例如world/view,我得到一個錯誤,AreaModel沒有定義。一旦我取消註釋該行,對於所有情況(即/周圍和/查看)再次正常工作。

我懷疑這與我「圈入口」的事實有關,例如world.py imports AreaModel,AreaModel import ActionModel和ActionModel import AreaModel。 我懷疑這是'pythonic way'做事情甚至'MVC的方式',所以我非常感謝你的啓發我如何正確地做到這一點。

注意:應用程序不在我的PYTHONPATH中,但我不認爲這是必要的,因爲start_app.py位於頂層目錄中,並且根據this,所有模塊都應該可用。

基本上,它所涉及的是: 我需要模型在控制器和模型中的功能。 「導入圈子」是否是一種好的做法?還是有更好的方法來做到這一點? 另外,這個問題是相關的一般python或只是web.py?

更新: 新增初始化 .py文件,我讓他們,但原來的問題沒有包括。對不起。

更新: ActionModel.py包括(其中包括)一類名爲BaseAction和一些功能,這些功能返回實例或取決於什麼類型的行動,我們正在處理BaseAction的子類。他們被稱爲使用例如ActionModel.get_by_id()

@馬修 - 特雷弗:你在一),我應該將這些功能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 

我不明白這應該如何補救我的進口問題。

回答

0

眼前的問題

無法從文件夾導入,但你可以進口包。您可以通過添加一個__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以區分它與類。

循環進口

它是很好的做法, 「在圈子裏輸入」?還是有更好的方法來做到這一點?

這不僅是不好的做法,它是行不通的。有幾種方法可以解決這個問題,這主要取決於你想要做什麼:

a。在AreaModel,導入ActionModel模塊,然後引用任何你想通過屬性查找,反之亦然它的使用方法:

# areamodel.py 
import actionmodel 

def foo(): 
    action = actionmodel.ActionModel(...) 

只要引用內部類或函數的定義,它只會發生在運行時而不是在導入過程中,所以避免了循環引用。

b。將models轉換爲模塊,並將ActionModelAreaModel代碼放入模塊中。

c。將ActionModelAreaModel的共享代碼/功能移到它們都從中導入的基本模塊中。 d)。讓你的ActionModel班(或其他)接受班級作爲輸入,然後在world.py(同上AreaModel)中通過AreaModel。這樣一來,ActionModel並不需要包含到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) 

這被稱爲對象組合。

+0

我有__init__.py文件,所以這不是問題。無論如何謝謝你指出。我加了他們。 – HereticPilgrim