Python 使用exec定义变量时,在引用变量时会引发NameError

Python 使用exec定义变量时,在引用变量时会引发NameError,python,exec,Python,Exec,我现在运行一个错误(首先,我已经知道使用exec不是最好的选择,但我现在不想讨论这个问题),关于引用变量时未定义变量。考虑到在我添加使用标准时间格式(1:36)之前,当我使用exec(f'oneMileMark.append(entry{I}.get())”)(此时它已经是一个浮点)时,它工作得非常好,我觉得很奇怪 范围内i的(numf): 如果i%4==0:#用于区分跑步者的姓名和不同的时间 exec(f'time=entry{i}.get()')#获取entry{i}的值并将其保存为时间 分

我现在运行一个错误(首先,我已经知道使用
exec
不是最好的选择,但我现在不想讨论这个问题),关于引用变量时未定义变量。考虑到在我添加使用标准时间格式(1:36)之前,当我使用
exec(f'oneMileMark.append(entry{I}.get())”)
(此时它已经是一个浮点)时,它工作得非常好,我觉得很奇怪

范围内i的
(numf):
如果i%4==0:#用于区分跑步者的姓名和不同的时间
exec(f'time=entry{i}.get()')#获取entry{i}的值并将其保存为时间
分,秒=时间。拆分(“:”)#将时间拆分为分和秒
newTime=float(分钟)+float(秒)/60#将分钟和小时合并为一个可编程项
oneMileMark.append(newTime)#将newTime添加到列表中
这就产生了错误:

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
回溯(最近一次呼叫最后一次):
文件“/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py”,第91行,in
app=应用程序(根)
文件“/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py”,第12行,in_u_init__
self.get_runner_data()
文件“/Users/Me/Desktop/Computer Programming/Python 3.x/Assignments/Programming 2/8/9_15 Computing 5k Mile Splits/main.py”,第53行,在get_runner_数据中
小时,分钟=时间。拆分(“:”)
NameError:未定义名称“时间”

基于您的回溯,您正在类的方法中使用,如下所示:

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(':')
        ... 
注意:如果要在模块级别(函数或类定义之外)使用
exec
,则任何变量赋值都将在全局命名空间上工作:

>>> exec('x = "Hello World"')
>>> x
'Hello World'