Python web2py:在模块中使用db(…)
我的控制器文件越来越大,所以我决定开始将其拆分为更小的方法,并将这些方法转换为多个模块文件。首先,这聪明吗?这是pythonic/web2py方式吗 无论如何,我在Modules部分创建了我的第一个模块文件my_module.py,其中已经有了uuu init_uuuuu.py。我在模块中定义了一个方法my_method。我在控制器中导入模块:导入我的\u模块并调用控制器中的方法:我的\u模块。我的\u方法 控制器:Python web2py:在模块中使用db(…),python,web2py,Python,Web2py,我的控制器文件越来越大,所以我决定开始将其拆分为更小的方法,并将这些方法转换为多个模块文件。首先,这聪明吗?这是pythonic/web2py方式吗 无论如何,我在Modules部分创建了我的第一个模块文件my_module.py,其中已经有了uuu init_uuuuu.py。我在模块中定义了一个方法my_method。我在控制器中导入模块:导入我的\u模块并调用控制器中的方法:我的\u模块。我的\u方法 控制器: import my_module ... def my_page():
import my_module
...
def my_page():
...
my_module.my_method()
...
my_module.my_method(db)
模块:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gluon import *
def my_method():
...
rows = db(db.my_table.my_field == x).select()
...
但是,现在它给了我一个错误:
文件/home/my_user/web2py/applications/my_app/controllers/default.py,第568行,在我的页面中
my_模块。my_方法
文件applications/my_app/modules/my_module.py,第10行,在my_方法中
rows=dbdb.my_table.my_field==x.select
NameError:未定义全局名称“db”
我正在做一些基本的数据库工作,当它在控制器中定义时,这个方法工作得很好。但是,为什么模块与控制器的工作方式不同呢?还有其他区别或注意事项吗?使用模块是否值得呢?web2py在一个准备好的环境中执行模型、控制器和视图文件,该环境在每个HTTP请求中都是新创建的。模型文件中定义的对象(包括db对象)将添加到此环境中,因此在任何控制器或视图中全局可用。但是,导入到控制器中的模块与任何其他Python模块的工作方式相同——它们不在web2py环境中执行,因此,web2py环境中的对象在导入的模块中不全局可用 在这种情况下,您有两种选择。首先,您可以简单地将db对象作为参数传递给函数: 在模块中:
def my_method(db):
在控制器中:
import my_module
...
def my_page():
...
my_module.my_method()
...
my_module.my_method(db)
或者,您可以将db对象添加到当前对象,并将当前导入模块,如文档所示:
在模型中:
from gluon import current
current.db = db
在您的模块中:
from gluon import current
def my_method():
db = current.db # Keep this inside the function, not at the top level of the module.
最后,请注意,您还可以通过current.globalenv字典访问web2py环境中的任何对象,因此您可以通过current.globalenv['db']简单地访问它,而不是显式地将db添加到current中。您应该将相关部分代码粘贴到此处,但看起来您不了解面向对象的原则。你说的是函数还是方法?是的,我用错了术语,现在就修好了。当然,它们是苹果和桔子。。。但它们的意思是完全相同的,如果我不是在谈论水果生意,也没关系。此外,我列出了代码的所有相关部分,但现在已修复,因此更易于查看。谢谢你的评论!非常感谢。因此,它似乎是最容易使用current.globalenv的,因为它允许以最直接的方式将函数从控制器剪切粘贴到模块。不需要一直传递巨大的db对象,或者如您所说,显式地将db添加到当前数据库中。但这一切让我想知道,使用模块值得吗?或者人们如何在web2py中拆分巨大的控制器文件?我不打算在其他地方使用这些模块,我只想拆分以便于阅读/开发。首先,db对象并不庞大,将其作为参数传递也没有影响,因为Python不会复制它。使用current.globalenv,您不能简单地将整个函数从控制器剪切/粘贴到模块-您仍然需要在移动的函数中添加对current.globalenv的引用。一般来说,我倾向于使用显式参数——使代码更清晰、简洁,并使测试更容易。至于是否值得,为什么不呢?从任何模块导入到任何其他模块时,都会遇到相同的问题。