最小例子
class foo:
loadings = dict(hi=1)
if 'hi' in loadings:
print(loadings['hi'])
# works
print({e : loadings[e] for e in loadings})
# NameError global name 'loadings' not defined
我也尝试引用类命名空间,但它不能正常工作
class foo:
loadings = dict(hi=1)
if 'hi' in loadings:
print(loadings['hi'])
#works
print({e : foo.loadings[e] for e in foo.loadings})
#NameError: name 'foo' is not defined
当然,这可以按预期工作
class foo:
loadings = dict(hi=1)
if 'hi' in loadings:
print(loadings['hi'])
print({e : foo.loadings[e] for e in foo.loadings})
我想理解为什么这个范围问题正在发生,如果我想做一些疯狂的事情,那么最好的方法就是这样做。我的感觉是第一个代码片段应该按原样运行,但当然不是。
目标
我正在为一些csv / json文件创建一个DataManager类/模块以及罐装数据库查询,这是我的程序的一站式商店和获取数据。有一些静态数据和一些动态数据,所以它似乎在同一个类中使用静态和非静态数据成员。虽然我理解这些可能是模块级变量,但我喜欢使用静态类数据成员的概念(可能是因为Java的偏见)。非常感谢任何帮助
我的解决方案(暂时)
我最终展开列表理解以保持在课堂范围内,在上面它会变成这样的
class foo:
loadings = dict(hi=1)
temp = dict()
for e in loadings:
temp[e] = loadings[e] # keep in mind this is a minimal example, I probably wouldn't do (just) this
print(temp) # works
del temp
它不漂亮,但现在可以使用
答案 0 :(得分:4)
类块中定义的名称范围仅限于该类 块;它没有扩展到方法的代码块 - 这个 包括理解和生成器表达式,因为它们是 使用函数范围实现。这意味着以下内容 失败:
class A: a = 42 b = list(a + i for i in range(10))
有关详细信息,请参阅this answer。
在Python2中,可以使用列表推导,因为它们是在不使用函数范围的情况下实现的:
dict([(e,loadings[e]) for e in loadings])
但是如果在Python3中运行,这段代码就会破坏。所以这是一个可以在Python2和Python3中使用的替代解决方法:
class Foo:
def loadings():
load = dict(hi=1)
if 'hi' in load:
print(load['hi'])
print({e:load[e] for e in load})
return load
loadings = loadings()
print(Foo.loadings)