标题可能不是我的问题的正确措辞,但我仍然是编程新手,尤其是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.py和https://github.com/jtsmith1287/gurpscg/blob/master/skills.py 如果您想查看应用程序的功能,只需加载http://gurpscgtest.appspot.com并刷新几次,然后查看表格。
答案 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