在类定义中执行语句:解释器知道哪些变量?

blz*_*blz 7 python

以下是我的部分类定义:

class Trial:
    font = pygame.font.Font(None, font_size)
    target_dic = {let: font.render(let, True, WHITE, BG) for let in list("ABCDEFGHJKLMNPRSTUVWX")}
Run Code Online (Sandbox Code Playgroud)

部分类定义的最后一行target_dic = {let: font.render(let, True, WHITE, BG) for let in list("ABCDEFGHJKLMNPRSTUVWX")返回错误:未定义全局名称"font".很公平.

但是,我尝试了以下测试用例并没有出现错误:

class x:
    dat = 1
    datlist = [dat for i in range(10)]
Run Code Online (Sandbox Code Playgroud)

为什么第一种情况不起作用?font到达字典理解时,成员是否存在?

我是否需要将这些操作移动到__init__或者是否可以在创建类对象时准确定义列表一次?

编辑:

为清楚起见,我希望能够在类对象创建时填充列表,以减少创建试用对象所花费的时间.

Bou*_*oud 4

部分答案,因为更多的是要切断一些错误的道路。

如果我收回你的工作样本并添加一个字典理解:

class x:
    dat = 1
    datlist = {i:dat for i in range(10)}
Run Code Online (Sandbox Code Playgroud)

我也得到这个:

>>> NameError: global name 'dat' is not defined
Run Code Online (Sandbox Code Playgroud)

因此,看起来字典理解隐藏了类语句执行期间临时字典的使用,但列表理解却没有。

目前在文档中没有找到关于此的更多信息......

根据 @interjay 评论进行编辑:这篇文章解决了不满足范围规范的类构造。简而言之,列表理解在 2.x 中存在错误,并且可以看到类成员,但他们不应该看到。

  • 2.x 中的列表推导式没有自己的作用域(在 3.x 中它们有,并且生成器表达式以及 dict/set 推导式在所有版本中都有它们)。它可能一开始是一个错误,而且很讨厌,但我*相信*它已被记录并保留以实现兼容性(包括得到其他 Python 解释器的支持)。我会查一下。 (2认同)