在python / GAE中声明全局变量的问题

时间:2009-10-25 16:02:55

标签: python google-app-engine

我是python的新手,我正在尝试从UI获取用户名并查询结果以获取用户的电话簿联系人。但是我无法将用户名设置为全局变量以将其用于多个查询。这是代码,我相信我正在做一些语法错误/不正确的使用,请帮助纠正我的代码。

#!/usr/bin/env python

import wsgiref.handlers
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
import models

class showPhoneBook(db.Model):
    username = db.StringProperty(required=True)

class MyHandler(webapp.RequestHandler):
    user_name = ''
    def get(self):
        p = db.GqlQuery('SELECT * FROM UserDetails WHERE user_name = $1', user_name)
        #p = UserDetails.gql('WHERE user_name = $1', user_name)
        result1 = p.fetch(1)
        for itr1 in result1:
            userId = itr.user_id
        q = db.GqlQuery('SELECT * FROM PhoneBook WHERE user_id = :1', userId)
        #q = PhoneBook.gql('WHERE user_id = :1', userId)
        values = {
            'phoneBookValues': q
        }
        self.request.out.write(
            template.render('phonebook.html', values))
    def post(self):
        global user_name
        phoneBookuserID = showPhoneBook(
            user_name = self.request.get(
                'username'))
        self.request.out.write(user_name)
        phonebookuserID.put()
        self.redirect('/')

def main():
    app = webapp.WSGIApplication([
        (r'.*',MyHandler)], debug=True)
    wsgiref.handlers.CGIHandler().run(app)

if __name__ == "__main__":
    main()

此处 UserDetails 电话簿是我 models.py

中定义的实体类

请帮助我找到错误...或者从UI获取后,可能会获得有关如何在查询中使用user_name的更正代码。

3 个答案:

答案 0 :(得分:8)

首先,App Engine的执行模式非常“松散” - 这就是它如此可扩展的原因!当请求到达您的URL时,GAE可能会重复使用已经运行您的脚本的现有流程,如果可以更好地平衡整体系统负载,它可能会启动另一个运行相同脚本的流程;一旦请求被提供,服务它的过程可能会停留或不停留,具体取决于系统是否与进程占用的内存有更好的关系。

因此,您必须以适用于任何一种情况的方式进行编码,而不必假设进程将在请求之间保持不变(并且不假设它也不会)。所以全局变量(在所有类型的编程中最常避免)是绝对不是要走的路!

在请求之间保留内容的唯一保证方法是将它们存储在数据库中;将cookie作为响应中的标题发送到用户的浏览器,因此所述浏览器将在下一个请求时将其发回,也可能是正常的(用户可能决定阻止其浏览器接受并重新发送cookie,但这是用户的决定,你不能真正做很多事情)。

“sesssion”的抽象概念可以封装这些选择并允许您在更高级别编程,并且许多框架提供某种会话,例如,请参阅gaeutilities,除非您已经在使用其他一些Web框架提供会话抽象。

您的代码还有许多其他特定问题(例如usernameuser_name之间的混淆,全局变量和类变量之间的混淆,以及缺少任何分配!),但是从与app引擎中使用全局变量的整个概念问题相比,这些都是小问题! - )

答案 1 :(得分:0)

Aaron Hampton在passing variables to a template on a redirect in python

回答

看起来它可能对你有用,也避免了其他人提到的全球变量的陷阱。

答案 2 :(得分:-1)

Simples!

您似乎将user_name存储为类变量,而不是全局变量。这里有一些棘手的行为,在方法中对它的引用将创建一个具有隐藏类变量的相同名称的实例变量。

class curious(object):
  hide = 11
  def get(self):
    return self.hide
  def put(self,x):
    print "before",self.hide
    self.hide = x
    print "after", self.hide

a = curious()
b = curious()
print a.hide,b.hide
a.put(23)
print a.hide,b.hide

注意对象b如何仍然具有对值11的引用,即使它在。

中更改后也是如此

不要那样做。通过在模块级别的任何类定义之外指定默认值,使其成为真正的全局变量。