numpy,scipy,在函数、模块之间轻松传递大量变量

numpy, scipy, pass large number of variables between functions, modules, easily

所以我正在使用 numpy、scipy、matplotlib 进行科学计算,运行进行一些模拟并尝试对它们进行模块化操作,我 运行ning成问题。尝试从 matlab 调整我的工作流程。

在 matlab 中,我通常会编写几个分布在单独文件中的函数 - 一个 运行 是一个以参数作为参数的模拟,一个是 运行 对这些模拟结果的评估在一个单独的函数中输入不同的参数值,根据参数等绘制结果和标题。通常参数集和结果集将是不同类型变量的非常大的组合,因此我会将它们打包到结构中。 matlab 中有一个名为 v2struct 的函数,可以轻松地在不同操作之间打包和解包这些变量组合 运行。另外,我似乎没有 运行 涉及 matlab 中的命名空间问题。

现在 python,我希望能够做同样的事情。我正在慢慢学习如何编写 classes,但我找不到关于如何在我的文件系统中组织这些内容的很好的文档。因为我更愿意编写函数和脚本(我认为这是正确的术语)并且 运行 将它们与 ipython %运行 script.py` 我想利用具有在各种函数之间传递大量参数和结果变量到 运行 模拟、测试结果并绘制结果的相同能力。这就是为什么我一直试图将东西打包到字典中,然后将它们解包到其他名称空间中。这将使我 100% 更容易地分解我已经完成的代码脚本,将这些模拟试验分成模块化的部分。

但每次我试图弄清楚如何去做时,我都会看到很多 "no one should ever be dynamically creating variables" 和 "i can't imagine why you would ever want to unpack a dictionary." 那么在函数周围传递字典有什么意义呢?我期望有很多不同的函数可以使用相同的变量集。是的,我知道这意味着 classes。但它们真的很难设计,至少对于科学计算而言。或者也许只是为了我。有中间立场吗?

是否有人有指向任何教您如何解决此问题的教程的链接?教你如何设计代码的资源(也就是我了解如何使用 python 从 900 亿 "intro to python" 教程中编写脚本,但是在弄清楚如何将我的脚本转换为模块方面存在差距,即重构)。我知道如何编写 class,但不知道如何选择如何将我的脚本放入 classes,或者何时将东西分成 subclasses,或者特别是如何使用我用我的一个脚本制作的 class。


好的,这是我找到的解决方案: 将我的脚本(所有共享一个命名空间)分解为函数(在相同的变量上工作,但在不同的命名空间中)我制作了一个键列表,('tuple','of','keys'),我用它来将我的函数命名空间中的变量打包到输出中词典:

returnVals = dict();
for k in keylist:
    returnVals[k]=locals()[k]

return returnVals

为了让事情变得更容易(我希望)我自己将参数名称自动打包到密钥列表中,如下所示:

argNames = my_function.func_code.co_varnames[:my_function.func_code.co_argcount]

然后是keynames = argNames + ('stuff','function','computes')

唯一有点烦人的是必须重写函数参数中的所有变量名(即def subfunction(sameVarName1,sameVarName2,etc):) 这样当我调用 subfunction(**whateverINamedMyReturnValsInLastFunction) 时,该函数就知道 kwargs 中将包含哪些键。但是,我认为这将在很长一段时间内帮助我 运行 当我(希望)能够重用我的代码时。

我基本同意"no one should ever be dynamically creating variables" 但强烈不同意“我[原文如此]无法想象为什么你会想要打开包装 字典。"[1]

Unpacking a dictionary 是解决您当前问题的好方法:

def foo():
    result = dict()
    # fill `result` with values
    result[key] = value
    ...
    return result

def bar(arg1, arg2, ...):
    ...

result = foo()
bar(**result)

最后一行解压 result 中的 key/value 对并将它们作为参数传递给 bar

bar(**{key1:value1, key2:value2})

相当于

bar(key1=value1, key2=value2)

我不认为 you really need to define a class 只是传递值。字典就可以了。


[1]嗯,转念一想,要看"unpacking a dictionary"是什么意思了。将字典解包到全局命名空间是个坏主意,但将字典解包到函数是好的。