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

1 投票
3 回答
2896 浏览
提问于 2025-04-15 15:21

我刚开始学习Python,想从用户界面获取用户名,然后查询这个用户的电话簿联系人。但是我无法把用户名设置为全局变量,以便在多个查询中使用。下面是我的代码,我觉得我可能在语法上出错了或者用法不对,请帮我纠正一下代码。

#!/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()

这里的UserDetailsPhonebook是我在models.py中定义的实体类。

请帮我找出错误……或者给我一个正确的代码,教我如何在从用户界面获取用户名后在查询中使用它。

3 个回答

-1

简单吧!

你似乎把 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

注意,尽管在 a 中改变了值,对象 b 仍然保持着值 11 的引用。

别这么做。要把它真正变成全局变量,应该在模块级别的类定义外面给它赋一个默认值。

0

这里是Aaron Hampton的回答,内容在Python中在重定向时传递变量到模板

看起来这个方法可能对你有帮助,而且还能避免其他人提到的全局变量带来的问题。

10

首先,App Engine的执行方式非常“灵活”,这也是它能扩展的原因!当有人访问你的网址时,GAE可能会重新使用一个已经在运行你脚本的进程,或者它可能会启动另一个进程来运行同样的脚本,这样可以更好地平衡系统的负载;一旦请求处理完毕,处理这个请求的进程可能会继续存在,也可能会消失,这取决于系统是否有更好的方式来利用这个进程占用的内存。

因此,你需要编写代码,使其在这两种情况下都能正常工作,而不能假设进程会在请求之间保持不变(也不能假设它不会保持不变)。所以,全局变量(在各种编程中通常都最好避免使用)绝对不是一个好选择!

在请求之间保持数据的唯一可靠方法是将它们存储在数据库中;另外,将一个cookie发送到用户的浏览器作为响应头,这样浏览器在下一个请求时会把它发回来,这也是可以的(用户可能会选择阻止浏览器接受和发送cookie,但这属于用户的选择,你对此也无能为力)。

抽象的“会话”概念可以封装这些选择,让你在更高的层次上编程,许多框架都提供某种形式的会话,比如可以查看gaeutilities,除非你已经在使用其他提供会话抽象的网络框架。

你的代码中还有许多其他具体问题(比如usernameuser_name之间的混淆,全局变量和类变量之间的混淆,以及对这两者都没有进行任何赋值!),但从某种意义上说,这些问题相比于在App Engine中使用全局变量的整体概念问题来说,算是小问题!-)

撰写回答