【问题标题】:How to reconstruct a local variable environment in python?如何在python中重建局部变量环境?
【发布时间】:2021-01-03 10:07:50
【问题描述】:

我正在重新格式化一堆数据处理代码。原代码首先声明了几个函数,它们具有一定的拓扑依赖关系(即某些函数依赖于其他函数的结果),然后依次调用它们(使用正确的拓扑排序):

def func_1(df):
    return df.apply(...)

def func_2(df):
    return pd.concat([df, ...])

def func_3(df_1, df_2):
    return pd.merge(df_1, df_2)

if __name__ == "__main__":
    df=...
    df_1 = func_1(df)
    df_2 = func_2(df)
    result = func_3(df_1, df_2)# the func_3 rely on the result of func_1 & func_2

问题是我无法检索中间数据。假设我只想应用 func_1 & func_2,我需要更改一些代码。当拓扑依赖变得复杂时,它就会变得复杂。

所以我想改成类似于 makefile 的递归配方:

def recipe_1(df):
    return df.apply(...)

def recipe_2(df):
    return pd.concat([df, ...])

def recipe_3(df):
    df_1 = recipe_1(df)
    df_2 = recipe_2(df)
    #some process here.
    return 

if __name__ == '__main__':
    df = ...
    recipe_3(df) #Just call the intermediate node I need.

这种方法的问题是我需要从recipe_3中的recipe_1recipe_2收集很多变量,所以我认为如果我能够从locals()中检索变量会很好,这将使#some process here. 中的其他代码保持不变。

现在我在想这样的事情,但看起来很丑:

def func_to_be_reconstructed():
    a = 3
    return locals()

local_variables = func_to_be_reconstructed()
for key in local_variables.keys():
    exec(str(key) + '= local_variables[\'' + str(key) + '\']')

更好的解决方案?

【问题讨论】:

  • 您到底想完成什么?你的用例是什么?
  • 这能回答你的问题吗? How do I create variable variables? TL;DR - 不要使用 exec 创建新变量,只需使用 loacals() 作为字典...
  • 这真的没有多大意义。

标签: python python-3.x eval


【解决方案1】:

globals()locals() 只是字典...

所以,不要以这种可疑的方式使用exec,而是使用update dict:

def func_to_be_reconstructed():
    a = 3
    return locals()

globals().update(func_to_be_reconstructed())

【讨论】:

  • 那么如果我想在另一个函数中使用它们,我可以在那个函数中使用 locals().update(func_to_be_reconstructed()) 吗?
  • 是的,虽然我很确定一个更好的方法就是 return 您需要从函数中获取的值并在其他地方重新使用它们......
【解决方案2】:

这看起来更干净一些,但基本上是一样的。

for var,value in func_to_be_reconstructed().items(): f"{var} = {value}")

【讨论】:

    【解决方案3】:

    这可能是一种不好的做法,但您可以在要在函数外部引用的变量上使用 global 关键字。

    def func_to_be_reconstructed():
        global a
        a = 3
    
    print(a)
    

    如果您只需要几个变量,这将特别有用。看看这个related question

    编辑:单个全局列表可以填充多个变量:

    def write_to_msv(*vars):
        global my_special_var
        my_special_var = []
        for k in vars:
            my_special_var.append(k)
    
    myvar1 = 123
    myvar2 = "hello"
    myvar3 = {'no shoes': 'no service'}
    
    write_to_msv(myvar1, myvar2, myvar3)
    
    print(my_special_var)
    

    再次:"You can use global variables but you shouldn't"

    【讨论】:

    • 如果他们有 10 个变量呢?如果有 50 个呢?
    • 在这种情况下,我可能会让函数返回列表或某种容器中的所有变量。检查上面的编辑,描述的方法是适用的。
    猜你喜欢
    • 2016-01-11
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 2011-08-23
    • 2013-01-24
    相关资源
    最近更新 更多