Sea*_*ean 1 python runtime-error python-3.x
我知道这里有很多类似的问题,但他们似乎都没有遇到我所遇到的问题。这是代码。
class Tournament(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(Tournament, self).__init__()
self.setupUi(self)
self.games = [Game(eval('self.combo' + str(i), globals(), locals())) for i in range(1, 15)]
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我在最后一行得到“NameError:名称'self'未定义”。我在列表理解之前和期间打印了 locals() ,它在列表理解之前显示“self”,但不在其中显示。所以我尝试将其保存到临时变量中
class Tournament(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(Tournament, self).__init__()
self.setupUi(self)
loc = locals()
self.games = [Game(eval('self.combo' + str(i), globals(), loc)) for i in range(1, 15)]
Run Code Online (Sandbox Code Playgroud)
我在最后一行得到了同样的错误。
谁能告诉我这里发生了什么事?我能够使用常规的“for”循环来解决它,但我真的很想了解为什么它不能以这种方式工作。
编辑:添加第二个示例中的完整错误消息
Traceback (most recent call last):
File "tournament.py", line 55, in <module>
interface = Tournament()
File "tournament.py", line 48, in __init__
self.games = [Game(eval('self.combo' + str(i)), globals(), loc) for i in range(1,15)]
File "tournament.py", line 48, in <listcomp>
self.games = [Game(eval('self.combo' + str(i)), globals(), loc) for i in range(1,15)]
File "<string>", line 1, in <module>
NameError: name 'self' is not defined
Run Code Online (Sandbox Code Playgroud)
编辑2:我比以往任何时候都更加困惑。我尝试编写一个精简的示例,该示例会出现相同的错误,但我无法再次出现该错误。所以我认为这与 PyQt 有关,所以我剥离了对 PyQt 的所有依赖项只是为了看看错误是否消失,但它仍然出现!
编辑 3. 根据要求的最小示例
class Game(object):
def __init__(self, combobox, next_game=None):
self.combobox = combobox
self.next_game = next_game
class Tournament():
def __init__(self):
self.combo1 = 1
self.combo2 = 2
self.combo3 = 3
self.combo4 = 4
loc = locals()
self.tournament = [Game(eval('self.combo' + str(i)), globals(), loc) for i in range(1, 4)]
if __name__ == '__main__':
interface = Tournament()
Run Code Online (Sandbox Code Playgroud)
问题是locals()列表理解内部没有执行您想要的操作:
>>> x = 12
>>> locals()
{..., 'x': 12}
>>> [locals() for i in range(1)]
[{'i': 0, '.0': <range_iterator object at 0x0000000003034DD0>}]
Run Code Online (Sandbox Code Playgroud)
请注意,x在字典中,whenlocals()是从当前作用域调用的,而不是whenlocals()是从列表理解调用的。原因是推导式是在其自己的范围内执行的,因此x在该范围内不是本地的。另一方面,例如,i推导式中使用的变量在推导式的范围内是本地的。
解决问题的直接方法是init_locals = locals()在正确的范围内进行分配,然后将其传递给理解。不幸的是,init_locals不会包含i来自推导式,所以我们需要传递一个包含init_locals和 推导式的字典locals()才能使用selfand i:
def __init__(self):
super(Tournament, self).__init__()
self.setupUi(self)
init_locals = locals()
self.games = [
Game(eval('self.combo' + str(i), globals(), { **init_locals, **locals() }))
for i in range(1, 15)
]
Run Code Online (Sandbox Code Playgroud)
一个更简单的选择是使用getattr而不是eval:
self.games = [
Game(getattr(self, 'combo' + str(i)))
for i in range(1, 15)
]
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您必须使用eval(或者在较小程度上使用getattr/ setattr)来初始化类实例,那么您应该重新考虑您的设计。如果您需要combo通过索引动态访问不同的s i,最好将它们存储在专为通过索引或键进行动态查找而设计的列表或字典中。
| 归档时间: |
|
| 查看次数: |
1242 次 |
| 最近记录: |