簡體   English   中英

在模塊中導入模塊時出現Web.py NameError

[英]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轉換為模塊,然后將ActionModelAreaModel代碼放入其中。

C。 ActionModelAreaModel的共享代碼/功能移動到它們都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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM