Web.py 模块导入时的 NameError 错误

2024-09-23 22:23:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用创建web应用网页.py在Python2.7.3上。 我有以下文件夹结构:

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时,我会得到以下错误

^{pr2}$

第13行很简单:from app.models import AreaModel,但我不明白python为什么在这里抱怨。在

如果我评论一下这个导入行,它运行得很好。但是,如果我调用一个不同的URL,例如world/view,就会得到一个错误:AreaModel没有定义。一旦我取消了对该行的注释,它对所有情况都能正常工作(即/arounding和/view)。在

我怀疑这与我“在圈子里导入”有关,也就是说。世界.py导入AreaModel,AreaModel导入ActionModel,ActionModel导入AreaModel。 我怀疑这是“Python式”的做事方式,甚至是“MVC方式”,所以我非常感谢你能启发我如何正确地做到这一点。在

注意:应用程序不在我的PYTHONPATH中,但我认为从一开始就不需要它了_应用程序副本在顶层目录中,并且根据this所有模块都应该可用。在

基本上,归根结底是: 我需要模型在控制器和模型中的功能。“圈内进口”是好做法吗?或者有更好的方法来做这件事吗? 另外,这个问题是与python有关还是仅仅与python有关web.py?在

更新: 添加了init.py文件,我有它们,但没有包含在原始问题中。对不起。在

更新: 动作模型.py根据其他类型的BaseAction,我们还包括了一些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

不过,我不明白这应该如何解决我的进口问题。在


Tags: py模型idapp应用程序worldgetby
1条回答
网友
1楼 · 发布于 2024-09-23 22:23:56

眼前的问题

您不能从文件夹导入,但可以从包中导入。您可以通过添加__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,以区别于类。在

循环进口

Is it good practice to "import in circles"? Or is there a nicer approach to do this?

这不仅是不好的做法,而且是行不通的。有几种方法可以解决这个问题,这主要取决于您要做什么:

a.在AreaModel中,导入ActionModel模块,然后通过属性查找引用要在其中使用的任何内容,反之亦然:

^{pr2}$

只要引用在类或函数定义内,它只会在运行时发生,而不会在导入期间发生,因此可以避免循环引用。在

b.将models转换为一个模块,并将ActionModel和{}代码都放进去。在

c.将ActionModelAreaModel的共享代码/功能移到它们都从中导入的基本模块中。在

让您的ActionModel类(或其他任何类)接受一个类作为输入,然后将AreaModel传递到actionmodel.py中(对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)

这就是所谓的对象合成。在

相关问题 更多 >