繁体   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