2014-01-29 47 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