Проблема объявления глобальной переменной в python / GAE - PullRequest
1 голос
/ 25 октября 2009

Я новичок в 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()

Здесь UserDetails и Телефонная книга - это мои классы сущностей, определенные в моих models.py

Пожалуйста, помогите мне найти ошибку ... или, возможно, получите исправленный код использования имени пользователя в запросах после получения его из пользовательского интерфейса.

Ответы [ 3 ]

8 голосов
/ 25 октября 2009

Прежде всего, модель исполнения App Engine довольно «свободна» - поэтому она так масштабируема! Когда приходит запрос на ваш URL, GAE может повторно использовать существующий процесс, который уже выполняет ваш скрипт, или , он может запустить другой процесс, выполняющий тот же скрипт, если это лучше уравновешивает общую загрузку системы; как только запрос обработан, обслуживающий его процесс может остаться или не зависеть, в зависимости от того, имеет ли система какое-то лучшее отношение к памяти, занимаемой процессом.

Поэтому вы должны кодировать таким образом, который работает в любой ситуации, не предполагая, что процесс будет зависать между запросами (и не предполагая, что не будет , либо). Таким образом, глобальные переменные (которых всегда лучше всего избегать во всех видах программирования) определенно не подходят!

Единственный гарантированный способ сохранить вещи между запросами - сохранить их в БД; отправка куки в браузер пользователя в качестве заголовка в вашем ответе, так что указанный браузер отправит его обратно при следующем запросе, также, вероятно, будет в порядке (пользователь может решить заблокировать свой браузер от принятия и повторной отправки куки, но это решение пользователя, и вы ничего не можете с этим поделать).

Абстрактная концепция "sesssion" может инкапсулировать эти варианты и позволить вам программировать на более высоком уровне, и многие фреймворки предлагают какой-то сеанс, например, смотрите gaeutilities , если вы уже не используете какой-то другой веб-фреймворк, обеспечивающий абстракцию сеанса.

Есть много других специфических проблем с вашим кодом (например, путаница между username и user_name, путаница между глобальными переменными и переменными класса и отсутствие какого-либо присвоения ни одному из них!), Но в некотором смысле это мелкие проблемы по сравнению со всей концептуальной проблемой использования глобалов в движке приложения! -)

0 голосов
/ 20 сентября 2012

Ответ Аарона Хэмптона здесь передача переменных в шаблон на редиректе в python

похоже, что это может сработать для вас, а также избежать ловушек глобальных переменных, как упоминалось другими.

0 голосов
/ 25 октября 2009

Simples!

Вы, похоже, храните имя пользователя как переменную класса, а не как глобальную. Здесь есть некоторое хитрое поведение, когда ссылка на него в методе создает переменную экземпляра с тем же именем, которая скрывает переменную класса.

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 даже после того, как он был изменен в.

Не делай этого. Сделайте его настоящей глобальной переменной, назначив значение по умолчанию вне определения любого класса на уровне модуля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...