使用 exec 定义变量,在引用它时引发 NameError
Using exec to define a variable, raises an NameError when referencing it
我现在 运行 一个关于变量的错误(首先我已经知道使用 exec
不是最好的选择,但我不想现在进入那个)引用它时未定义。在我添加使用标准时间格式 (1:36) 的能力之前,考虑到它在我使用 exec(f'oneMileMark.append(entry{i}.get())')
(此时它已经是一个浮点数)时工作得非常好,我觉得很奇怪。
for i in range(numOfRunners):
if i%4 == 0: # used to distinguish between a runner's name and different times
exec(f'time = entry{i}.get()') # gets the value of entry{i} and saves it as time
minutes,seconds=time.split(':') # splits time into mins and secs
newTime=float(minutes) + float(seconds)/60 # combines the minutes and hours into one bariable
oneMileMark.append(newTime) # adds newTime to a list
给出错误:
Traceback (most recent call last):
File "/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py", line 91, in <module>
app = Application(root)
File "/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py", line 12, in __init__
self.get_runner_data()
File "/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py", line 53, in get_runner_data
hours,minutes=time.split(':')
NameError: name 'time' is not defined
基于你的回溯和 , you are using exec
在一个 class 的方法中,像这样:
class Foo:
def bar(self):
exec('x = "Hello World"')
print(x)
当 exec
在没有 globals
参数的函数定义中执行时,它创建的任何变量都被分配给一个新的临时名称空间,无法访问。本质上,您的 time
变量是在内部范围内创建的(在 exec 完成后被丢弃),因此您无法在该范围之外访问它。
>>> Foo().bar()
Traceback (most recent call last):
...
File "..\main.py", line 4, in bar
print(x)
NameError: name 'x' is not defined
为什么你以前的 exec() 以前工作是因为它只访问 oneMileMark
并用 .append()
改变列表,并且没有尝试为变量分配新的东西。
要解决这个问题,您可以使用 eval
而不是 exec
,这样您就可以计算表达式,同时保持变量赋值保持在同一范围内:
for i in range(numOfRunners):
if i%4 == 0:
time_ = eval(f'entry{i}.get()')
minutes,seconds=time_.split(':')
...
注意:如果您要在模块级别(在函数或 class 定义之外)使用 exec
,则任何变量赋值都将在全局命名空间上起作用:
>>> exec('x = "Hello World"')
>>> x
'Hello World'
我现在 运行 一个关于变量的错误(首先我已经知道使用 exec
不是最好的选择,但我不想现在进入那个)引用它时未定义。在我添加使用标准时间格式 (1:36) 的能力之前,考虑到它在我使用 exec(f'oneMileMark.append(entry{i}.get())')
(此时它已经是一个浮点数)时工作得非常好,我觉得很奇怪。
for i in range(numOfRunners):
if i%4 == 0: # used to distinguish between a runner's name and different times
exec(f'time = entry{i}.get()') # gets the value of entry{i} and saves it as time
minutes,seconds=time.split(':') # splits time into mins and secs
newTime=float(minutes) + float(seconds)/60 # combines the minutes and hours into one bariable
oneMileMark.append(newTime) # adds newTime to a list
给出错误:
Traceback (most recent call last):
File "/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py", line 91, in <module>
app = Application(root)
File "/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py", line 12, in __init__
self.get_runner_data()
File "/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py", line 53, in get_runner_data
hours,minutes=time.split(':')
NameError: name 'time' is not defined
基于你的回溯和 exec
在一个 class 的方法中,像这样:
class Foo:
def bar(self):
exec('x = "Hello World"')
print(x)
当 exec
在没有 globals
参数的函数定义中执行时,它创建的任何变量都被分配给一个新的临时名称空间,无法访问。本质上,您的 time
变量是在内部范围内创建的(在 exec 完成后被丢弃),因此您无法在该范围之外访问它。
>>> Foo().bar()
Traceback (most recent call last):
...
File "..\main.py", line 4, in bar
print(x)
NameError: name 'x' is not defined
为什么你以前的 exec() 以前工作是因为它只访问 oneMileMark
并用 .append()
改变列表,并且没有尝试为变量分配新的东西。
要解决这个问题,您可以使用 eval
而不是 exec
,这样您就可以计算表达式,同时保持变量赋值保持在同一范围内:
for i in range(numOfRunners):
if i%4 == 0:
time_ = eval(f'entry{i}.get()')
minutes,seconds=time_.split(':')
...
注意:如果您要在模块级别(在函数或 class 定义之外)使用 exec
,则任何变量赋值都将在全局命名空间上起作用:
>>> exec('x = "Hello World"')
>>> x
'Hello World'