[英]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.