Google App Engine - Python 2.7 - “持久性内存”问题?

时间:2013-08-25 04:04:18

标签: google-app-engine python-2.7

标题可能不是我的问题的正确措辞,但我仍然是编程新手,尤其是Web开发之类的新手。

在普通的python环境中,对变量的引用不会影响原始对象。所以:

x = 1
y = x
y += 1
print x,y
>>> 1, 2

同样,如果我这样做......

x = [[1,2], [3,4]]
y = x[0]
z = y[0] + 1
print x
>>> [[1, 2], [3, 4]]

但是,在Google App Engine中,如果我执行上面的示例,我会得到:

print x
>>> [[2, 2], [3, 4]]

所以,我的问题是这个。 WTF?

我有一个类似于x的列表,但是更大,我访问(不修改)并使用该数据构建其他列表。当我然后更改新列表的内容时,它也会更改原始列表中的内容。因此,当我刷新网页时,我希望得到与首次加载时相似的结果,但原始列表完全改变了。之后每次刷新都会让事情变得越来越糟。现在,我花了很多时间逐行查看我的所有代码,现在我确信它不是我的代码。那么,GAE的工作方式与我预期的不同吗?这是正常的行为吗?更重要的是,我究竟如何解决它(让它像普通的python解释器一样工作)?

编辑:

好的,所以我刚刚确认了。我有一个名为SKILLS的全局不可变常量。然后我做all_skills = SKILLS。稍后我循环遍历all_skills并提取10个随机技能(SKILLS是一个包含表示游戏技能的列表的元组)并将它们分配给类实例变量。然后我确认SKILLS未经修改,然后修改了类变量,当我重新检查SKILLS时,所有在类变量中更改的技能也在SKILLS中更改,除非我完全误解了某些内容,否则这是不可能的。

如果您更加好奇,可以查看有问题的两个模块https://github.com/jtsmith1287/gurpscg/blob/master/charbuilder.pyhttps://github.com/jtsmith1287/gurpscg/blob/master/skills.py 如果您想查看应用程序的功能,只需加载http://gurpscgtest.appspot.com并刷新几次,然后查看表格。

2 个答案:

答案 0 :(得分:0)

您是在开发服务器中看到这个,还是在部署时看到了这个?如果是前者,那么我真的很惊讶 - 我们不会做任何改变Python核心语义的事情。

如果您在部署到appspot.com时看到这一点,那么您是否可能正在更改全局变量并期望在请求中显示该更改?如果是这种情况,则有一个简单但很明显的解释:顺序请求不能保证由应用程序的同一实例提供服务。这是App Engine的功能之一:传入请求速率的提高会导致启动更多实例,从而可以分散负载的增加。 (如果启用了多线程,这种情况会慢一些。)

归结为GAE环境全局主要用作不可变值的缓存。

答案 1 :(得分:0)

我的本​​地dev_appserver没有发生,我正在使用appengine 1.7.5。它可能是导致此行为的代码中的其他内容

import webapp2

class MainPage(webapp2.RequestHandler):
    def get(self):
        x = [[1, 2], [3, 4]]
        y = x[0]
        z = y[0] + 1
        print x , y , z

app = webapp2.WSGIApplication(
    [
     ('/', MainPage)],
    debug=True)

结果

[[1,2],[3,4]] [1,2] 2状态:200内容类型:text / html; charset = utf-8 Content-Length:0 Cache-Control:no-cache