python – 在理解另一个类变量时引用类变量
这可能是一个简单的问题,但我无法进行独特的搜索.
我有一个定义静态字典的类,然后尝试静态地定义该字典的子集. 所以,作为玩具的例子: class example(object): first_d = {1:1,2:2,3:3,4:4} second_d = dict((k,first_d[k]) for k in (2,3)) 这会产生NameError:未定义全局名称“first_d” 我该怎么做这个参考?似乎这种模式适用于其他情况,例如: class example2(object): first = 1 second = first + 1 解决方法
基本列表理解具有以下
syntax
[expression for var in iterable] 当列表理解发生在类中时,类的属性 但是,类的属性可以在Python2中的表达式中使用(即访问),但不能在Python3中使用. 生成器表达式的故事有点不同: (expression for var in iterable) 虽然仍可以从iterable访问类属性,但无法从表达式访问类属性. (这适用于Python2和Python3). 这可以总结如下: Python2 Python3 Can access class attributes -------------------------------------------------- list comp. iterable Y Y list comp. expression Y N gen expr. iterable Y Y gen expr. expression N N dict comp. iterable Y Y dict comp. expression N N (在这方面,Dict理解与生成器表达式的行为相同.) 现在,这与您的问题有什么关系: 在你的例子中, second_d = dict((k,3)) 发生NameError是因为无法从生成器表达式的表达式部分访问first_d. Python2的解决方法是将生成器表达式更改为列表解析: second_d = dict([(k,3)]) 但是,我发现这不是一个非常舒服的解决方案,因为此代码在Python3中会失败. 你可以像Joel Cornett建议的那样做: second_d = {k: v for k,v in first_d.items() if k in (2,3)} 因为它在iterable中使用first_d而不是dict理解的表达式部分.但是如果first_d包含许多项目,这可能会循环通过更多项目. Neverthess,如果first_d很小,这个解决方案可能就好了. 通常,您可以通过定义可在类内部或外部定义的辅助函数来避免此问题: def partial_dict(dct,keys): return {k:dct[k] for k in keys} class Example(object): first_d = {1:1,4:4} second_d = partial_dict(first_d,(2,3)) class Example2(object): a = [1,2,3,4,5] b = [2,4] def myfunc(A,B): return [x for x in A if x not in B] c = myfunc(a,b) print(Example().second_d) # {2: 2,3: 3} print(Example2().c) # [1,5] 函数起作用是因为它们定义了局部范围和 这是explained here,但我对此并不完全满意,因为它没有解释为什么表达式部分的行为与列表理解,生成器表达式或字典理解的可迭代部分不同. 因此,我无法(完全)解释为什么Python会以这种方式运行,只是这就是它的行为方式. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |