Pau*_*aul 5 python google-app-engine
在appengine应用程序中,我想为对象列表构建一组所有属性名称.这应该是相当简单的:
users = security.User.all().fetch(1000)
props = set([k for k in u.properties().keys() for u in users])
Run Code Online (Sandbox Code Playgroud)
但是,上面的代码会导致错误:
File "/Users/paulkorzhyk/Projects/appengine-flask-template/app/app.py", line 70, in allusers
props = set([k for k in u.properties().keys() for u in users])
UnboundLocalError: local variable 'u' referenced before assignment
Run Code Online (Sandbox Code Playgroud)
在调试器中进行了一些实验后,我注意到添加虚拟表达式修复了代码:
users = security.User.all().fetch(1000)
[u.properties().keys() for u in users]
props = set([k for k in u.properties().keys() for u in users])
Run Code Online (Sandbox Code Playgroud)
这对我来说非常违反直觉,为什么原始版本在Python 2.7中失败?为什么在中间添加一个"无用的"表达式来修复问题?
只需更改评估顺序即可
props = set([k for k in u.properties().keys() for u in users])
Run Code Online (Sandbox Code Playgroud)
至
props = set([k for u in users for k in u.properties().keys() ])
Run Code Online (Sandbox Code Playgroud)
你也不需要列表理解,但是具有集合理解的生成器表达式可以在这里工作
props = set(k for u in users for k in u.properties().keys() )
Run Code Online (Sandbox Code Playgroud)
评估顺序是从右到左
在你的原始表达中
set([k for k in u.properties().keys() for u in users])
Run Code Online (Sandbox Code Playgroud)
可以打破
for k in u.properties().keys(): # Here u is undefined
for u in users:
#what ever
Run Code Online (Sandbox Code Playgroud)
使用Dummy表达式的有趣现象是List Comprehension Leaks Variables导致u在全局范围内泄露的事实
所以
[u.properties().keys() for u in users]
Run Code Online (Sandbox Code Playgroud)
泄漏u在全球范围内,
这使得
set([k for k in u.properties().keys() for u in users])
Run Code Online (Sandbox Code Playgroud)
合法
以下示例显示了列表推导如何泄漏变量
>>> del i
>>> foo = [range(1,10) for _ in range(10)]
>>> globals()['i']
Traceback (most recent call last):
File "<pyshell#84>", line 1, in <module>
globals()['i']
KeyError: 'i'
>>> [i for i in foo]
[[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9]]
>>> globals()['i']
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
Run Code Online (Sandbox Code Playgroud)