【问题标题】:Problem declaring global variable in python/GAE在 python/GAE 中声明全局变量的问题
【发布时间】:2009-10-25 16:02:55
【问题描述】:

我是 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()

这里 UserDetailsPhonebook 是我在 models.py

中定义的实体类

请帮助我找出错误...或者在从 UI 获取用户名后,获取有关如何在查询中使用用户名的更正代码。

【问题讨论】:

  • 你没有提到实际发生的事情是错误的。这会让人们更容易帮助你。
  • 我确实提到了我的问题...我无法将 user_name 值从 post 方法传递到 get 方法,以便我可以使用该值进行查询。但是我不能让它成为一个全局变量来在不同的函数中访问它。

标签: python google-app-engine


【解决方案1】:

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

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

在请求之间持久化的唯一保证方法是将它们存储在数据库中;将cookie作为响应中的标头发送到用户的浏览器,因此所述浏览器将在下一个请求时将其发送回,也可能没问题(用户可能决定阻止他的浏览器接受和重新发送cookie,但这就是用户的决定,而您对此无能为力)。

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

您的代码还有许多其他具体问题(例如 usernameuser_name 之间的混淆,全局变量和类变量之间的混淆,以及缺少任何赋值!),但从某种意义上说,这些是与在应用引擎中使用全局变量的整个概念问题相比,这是小问题!-)

【讨论】:

    【解决方案2】:

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

    看起来它可能对您有用,并且还避免了其他人提到的全局变量的陷阱。

    【讨论】:

      【解决方案3】:

      简单!

      您似乎将 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,即使在 a 中更改后也是如此。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-02
        • 2015-05-11
        • 1970-01-01
        • 2020-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多