简体   繁体   English

在python / GAE中声明全局变量时出现问题

[英]Problem declaring global variable in python/GAE

I'm new to python and I'm trying to obtain a username from the UI and query the result to get the phone book contacts of the user. 我是python的新手,正在尝试从UI获取用户名并查询结果以获取用户的电话簿联系人。 But I am not able to set the user name to be a global variable to use it for multiple queries. 但是我无法将用户名设置为全局变量,以将其用于多个查询。 Here's the code, I believe I am doing some syntax error/improper usage, please help out in correcting my code. 这是代码,我相信我在做一些语法错误/用法不当,请帮忙纠正我的代码。

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

Here UserDetails and Phonebook are my entity classes defined in my models.py 这里的UserDetailsPhonebook是我在models.py中定义的实体类

Please Help me in finding the error...or possibly get a corrected code of how to use user_name in queries after obtaining it from the UI. 请帮助我查找错误...或者在从UI中获取用户名后,可能会获得关于如何在查询中使用user_name的更正代码。

First and foremost, App Engine's execution model is quite "loose" -- that's why it's so scalable! 首先,App Engine的执行模型非常“宽松”-这就是为什么它如此可扩展! When a request arrives for your URL, GAE may reuse an existing process that's already running your script, or it may start another process running the same script if that balances overall system load better; 当请求到达您的URL时,GAE可能会重用已经在运行您的脚本的现有进程, 或者如果可以更好地平衡整个系统负载,则它可能会启动另一个运行同一脚本的进程。 once the request is served, the process that served it may stick around or not, depending on whether the system has something better to do with the memory that the process is occupying. 一旦满足了请求,则根据系统是否与该进程所占用的内存有更好的关系,处理该请求的进程可能会一直存在或不存在。

You must therefore code in a way that works in either situation, without assuming that the process will stick around between requests (and without assuming it won't , either). 因此,必须在这两种情况下,(无论是和而不承担也不会 )的作品而不承担这一进程将坚持请求之间围绕路码。 So global variables (most always best avoided in all kinds of programming) are definitely not the way to go! 因此,全局变量(在各种编程中通常最好避免使用) 绝对不是要走的路!

The only guaranteed way to persist things between requests is to store them in the db; 在请求之间持久化事务的唯一保证方法是将它们存储在db中。 sending a cookie to the user's browser as a header in your response, so said browser will send it back on the next request, is also likely to be OK (the user may decided to block his browser from accepting and resending cookies, but that's the user's decision and you can't really do much about it). 将Cookie作为响应中的标头发送到用户的浏览器,因此该浏览器会在下一个请求时将其发送回去,这也可能没问题(用户可能决定阻止其浏览器接受和重新发送Cookie,但这就是用户的决定,那么您就不能做太多事情了。

The abstract concept of a "sesssion" can encapsulate these choices and let you program at a higher level and many frameworks offer some kind of session, for example see gaeutilities unless you're already using some other web framework supplying a session abstraction. “会话”的抽象概念可以封装这些选择,并允许您进行更高级别的编程,并且许多框架都提供某种会话,例如,请参见gaeutilities,除非您已经在使用其他提供会话抽象的Web框架。

There are many other specific issues with your code (such as confusion between username and user_name , confusion between global variables and class variables, and the lack of any assignment to either!), but in a sense these are minor issues compared to the whole conceptual problem of using globals in app engine!-) 您的代码还有很多其他特定的问题(例如, usernameuser_name之间的混淆,全局变量和类变量之间的混淆以及对这两个变量的任何赋值都没有!),但从某种意义上说,与整个概念相比,这些都是较小的问题在应用程序引擎中使用全局变量的问题!-)

Answer by Aaron Hampton here passing variables to a template on a redirect in python 亚伦·汉普顿(Aaron Hampton)的回答是在python中通过重定向将变量传递给模板

looks like it might work for you, and also avoid the pitfalls of global vars as mentioned by others. 看起来它可能对您有用,并且还避免了其他人提到的全局变量的陷阱。

Simples! 简单!

You seem to be storing user_name as a class variable, not a global. 您似乎将user_name存储为类变量,而不是全局变量。 There is some tricky behavior here where a reference to it in a method will create an instance variable with the same name that hides the class variable. 这里有一些棘手的行为,方法中对它的引用将创建一个名称相同的实例变量,该实例变量将隐藏类变量。

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

Notice how object b still has a reference to the value 11, even after it is changed in a. 请注意,即使在a中更改了对象b,它仍然如何引用值11。

Don't do that. 不要那样做 Make it a real global variable by assigning the default value outside of any class definition at the module level. 通过在模块级别的任何类定义之外分配默认值,使其成为真实的全局变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM