我的控制器文件变得非常庞大,所以我决定开始将它拆分为更小的方法并将方法转换为多个模块文件。首先,这是聪明的吗?这是pythonic / web2py方式吗?
无论如何,我在模块部分创建了我的第一个模块文件a<- structure(list(time = c("00:00", "00:01", "00:02", "00:03", "00:04",
"00:05", "00:06", "00:07", "00:08", "00:09", "00:10", "00:11",
"00:12"), day1 = c(1.2, 1.4, 1.4, 1.5, 0.7, 0.8, 0.69, 1.2, 1,
1.3, 0.6, 0.2, 0), day2 = c(0, 0, 0, 0, 0, 0, 96.6, 0, 0, 0,
0, 0, 0)), .Names = c("time", "day1", "day2"), row.names = c(NA,
-13L), class = "data.frame")
a$time<-as.POSIXct(a$time, format="%H:%M")
(其中已经有my_module.py
)。我在模块中定义了一个方法__init__.py
。我在控制器中导入模块:my_method()
并调用控制器中的方法:import my_module
控制器:
my_module.my_method()
模块:
import my_module
...
def my_page():
...
my_module.my_method()
...
然而,现在它给了我错误:
文件“/home/my_user/web2py/applications/my_app/controllers/default.py”,第568行,在my_page中
my_module.my_method()
文件“applications / my_app / modules / my_module.py”,第10行,my_method
rows = db(db.my_table.my_field == x).select()
NameError:未定义全局名称“db”
我正在做相当基本的数据库内容,并且该方法在控制器本身中定义时工作正常。但为什么模块的工作方式与控制器不同?还有其他差异或警告吗?使用模块甚至值得吗?
答案 0 :(得分:1)
web2py在准备好的环境中执行模型,控制器和视图文件(在每个HTTP请求中都是新创建的)。模型文件中定义的对象(包括db
对象)将添加到此环境中,因此可在任何控制器或视图中全局使用。但是,导入控制器的模块与任何其他Python模块的工作方式相同 - 它们不在web2py环境中执行,因此,web2py环境中的对象在导入的模块中不是全局可用的。
在这种情况下,您有几个选项。首先,您可以简单地将db
对象作为参数传递给函数:
在模块中:
def my_method(db):
在控制器中:
my_module.my_method(db)
或者,您可以将db
对象添加到current
对象并将current
导入到模块中(如文档here所示):
在模型中:
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环境中的任何对象,因此您可以通过{db
轻松访问current
,而不是明确地将current.globalenv['db']
添加到ReadString('\n')
。 {1}}。