Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python web2py:在模块中使用db(…)_Python_Web2py - Fatal编程技术网

Python web2py:在模块中使用db(…)

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():

我的控制器文件越来越大,所以我决定开始将其拆分为更小的方法,并将这些方法转换为多个模块文件。首先,这聪明吗?这是pythonic/web2py方式吗

无论如何,我在Modules部分创建了我的第一个模块文件my_module.py,其中已经有了uuu init_uuuuu.py。我在模块中定义了一个方法my_method。我在控制器中导入模块:导入我的\u模块并调用控制器中的方法:我的\u模块。我的\u方法

控制器:

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的引用。一般来说,我倾向于使用显式参数——使代码更清晰、简洁,并使测试更容易。至于是否值得,为什么不呢?从任何模块导入到任何其他模块时,都会遇到相同的问题。