Python dt没有在我的函数中定义,但是当我删除函数时它会工作吗?

Python dt没有在我的函数中定义,但是当我删除函数时它会工作吗?,python,Python,当我删除pandas()时,它可以正常工作,但当我包装它时,它说“dt”没有定义,但我是用exec定义的???关于python,是否有我不知道的地方我做错了 def myFunction(): exec('dt=relativedelta('+TIME+')') print("dt is ", dt) dt_today=datetime.date.today() START_DATE=pd.to_datetime(dt_

当我删除pandas()时,它可以正常工作,但当我包装它时,它说“dt”没有定义,但我是用exec定义的???关于python,是否有我不知道的地方我做错了

    def myFunction():
      exec('dt=relativedelta('+TIME+')')
      print("dt is ", dt)
      dt_today=datetime.date.today()
      START_DATE=pd.to_datetime(dt_today-dt) 
      print("start date is ", START_DATE)

      df['alias'] = np.where((df[NAME] == mylift), myalias, df.alias)
    
      DATA=df.loc[(df.alias.str.contains(ALIAS)) & (df[DATE] <= TODAY) & (df[DATE] >= START_DATE) ].loc[:,[DATE,'record','alias',NAME]]
        if DATA.empty:
            print("Data Frame is empty, check variables in 'dataFrame=df.loc...'"); exit()
def myFunction():
exec('dt=relativedelta('+TIME+'))
打印(“dt为”,dt)
dt_today=datetime.date.today()
开始日期=pd.到日期时间(dt\U今天-dt)
打印(“开始日期为”,开始日期)
df['alias']=np.where((df[NAME]==mylift),myalias,df.alias)
DATA=df.loc[(df.alias.str.contains(alias))&(df[DATE]=START_DATE)].loc[:,[DATE,'record','alias',NAME]]
如果DATA.empty:
打印(“数据框为空,检查'dataFrame=df.loc…'中的变量”);退出()
回溯(最近一次呼叫最后一次):
文件“/chart.py”,第186行,在
main()
文件“/chart.py”,第72行,主
myFunction()
文件“/chart.py”,第95行,在myFunction中
打印(“dt为”,dt)
NameError:未定义名称“dt”

正如一些评论已经指出的那样,这里首先不需要使用
exec
。但是,让我简单地解释一下为什么它在全局范围内工作,而不是在函数范围内工作

简而言之:出现错误是因为Python认为第3行的
dt
必须是全局变量,因此查找全局变量
dt
。如果在函数外部运行
exec()
,它将定义全局变量
dt
,一切正常。如果在函数中运行它,它不会定义全局变量,程序将中断

本地人和全球人 从概念上讲,Python将变量存储在字典中。您可以通过函数
globals()
locals()
访问这些。例如,如果运行以下代码:

def foo(x):
y=x+1
打印(globals())
打印(局部变量())
数字=123
t=45
傅(编号)
您将获得输出(我在这里省略了globals字典中的很多内容):

Python查看您的代码,发现
t
不是局部变量!因此,这一行被翻译成
局部变量['y']=局部变量['x']+全局变量['t']
。注意,它假定
t
必须是全局的,因为它没有在
foo
中定义

使用
exec
如果您在
foo
内部使用
exec(“t=…”)
,您会遇到麻烦<当然,code>exec本身试图将变量
t
定义为
foo
中的局部变量。但是Python没有查看
exec
字符串的内部,因此没有看到有一个局部变量
t
。对
t
的任何使用仍然被翻译成
globals['t']
而不是
locals['t']

不幸的是,局部变量的内部设计意味着
exec()
无法真正定义或更改局部变量。因此,像这样使用
exec()
永远不会完全起作用。如果您真的遇到了绝对需要执行类似操作的情况,请尝试使用
eval()

def myFunction():
dt=评估(“相对偏差(“+时间+”))
...
然而,请注意,正如其他评论人士已经指出的那样,在目前的情况下,绝对没有必要这样做。你可以写:

def myFunction():
dt=相对温差(时间)
...
这里有一个非常简单的经验法则:


“只要您想使用
exec()
eval()
,请不要使用!”

谢谢您的回答。我解决了我所有的问题,我希望这篇文章能帮助其他人

  • Python处理作用域的方式与其他语言不同。我必须在一些函数中传递参数以使事情正常工作,并在另一个函数中添加全局df以修复我的一个问题
  • “执行官”的事。我不知道relativedelta使用kwargs。所以我通过创建一个字典并传递它来解决这个问题。我的错误是我试图传递一个字符串

  • 尝试重命名函数。首先,您想使用什么
    exec
    ?这几乎总是表明你应该以不同的方式做事情——不管怎么说,这在这里似乎完全没有必要。我做过,它曾经是一个例子,在你的函数中dt在哪里,你需要将dt声明为一个局部变量为什么要在这个exec语句中包装它?只需使用dt=relativedelta(TIME)否?这是一个非常令人印象深刻的答案,唯一困扰我的是建议使用
    eval
    。或者完全删除它,或者如果你想保留它的完整性-至少添加一个足够的关于它的警告use@Tomerikoo谢谢我想我们都同意,在这里使用
    eval
    exec
    不是一个好主意(正如评论者多次提到的,我在最后试图捕捉到的)。然而,我认为,在这种情况下,问题还不足以保证发出“警告”,而且使用
    eval
    /
    exec
    可能还有其他合法的用例。使用
    eval
    的建议并非针对手头的实际代码,而是作为
    exec
    不起作用时的替代方法。
    Traceback (most recent call last):
      File "./chart.py", line 186, in <module>
        main()
      File "./chart.py", line 72, in main
        myFunction()
      File "./chart.py", line 95, in myFunction
        print("dt is ", dt)
    NameError: name 'dt' is not defined
    
    {..., 'foo': <function foo at 0x12345678>, 'number': 123, 't': 45}
    {'x': 123, 'y': 124}
    
    def myFunction():
         global df
    
    dt=relativedelta(**TIME)