下面是我的部分类定义:
class Trial:
font = pygame.font.Font(None, font_size)
target_dic = {let: font.render(let, True, WHITE, BG) for let in list("ABCDEFGHJKLMNPRSTUVWX")}
分部类定义的最后一行,target_dic = {let: font.render(let, True, WHITE, BG) for let in list("ABCDEFGHJKLMNPRSTUVWX")
返回错误:未定义全局名称“font”。很公平。在
但是,我尝试了以下测试用例,没有错误:
^{pr2}$为什么第一个案子不起作用?在达到字典理解时,成员font
不存在吗?在
我需要将这些操作移动到__init__
还是可以在创建类对象时只定义一次列表?在
编辑:
为了清楚起见,我希望能够在类对象创建时填充列表,以减少创建试用对象所花费的时间。在
在类创建过程中可用的名称是全局变量,并且名称已经在类的顶层定义(也就是说,随着名称的定义,它们在类代码的后面变得可用)。在
请注意,类级别的对象可能不是通过实例获得的,甚至不是通过类对象获得的;最明显的是,在类创建过程中,
def
的结果仍然是函数而不是方法。在关于OP的代码,这个例子显示了
font
是在类级别定义的:这就产生了:
^{pr2}$在(http://ideone.com/aC7VY)在
font
可按预期传递给lambda。在问题在于类作用域中没有可用的名称(
font
在那里可用)。问题是理解引入了一个新的范围(在python3中):http://docs.python.org/py3k/reference/expressions.html#displays-for-lists-sets-and-dictionaries因为类decorator是在类创建之后调用的,所以可以使用它来解决在类主体中引用类属性的限制,并有效地“后处理”刚刚创建的类并添加任何缺少的属性:
另一种方法是使属性最初成为一个数据描述符(也称为“属性”),该描述符(仅)在第一次读取属性时被调用。这是通过用计算出的值覆盖描述符来完成的,因此它只发生一次。在
^{pr2}$也有其他的方法来做这类事情,比如使用元类或者定义一个
__new__
方法,但是令人怀疑的是,任何一种方法都能更好地工作,或者不那么复杂。在部分回答,因为这更多的是切断一些错误的道路。在
如果我把你的工作样本拿回来,做一个口述理解:
我也知道:
^{pr2}$所以看起来dict comprehension隐藏了类语句执行期间dict的临时dict使用,但是list comprehension没有
到目前为止,在文档中找不到关于这个的更多信息。。。在
根据@interjay评论编辑: 不满足作用域规范的类构造在post中进行了处理。简而言之,在2.x中,列表理解是有缺陷的,并且可以看到类成员,但他们不应该这样做
相关问题 更多 >
编程相关推荐