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"是什么意思了。将字典解包到全局命名空间是个坏主意,但将字典解包到函数是好的。
所以我正在使用 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"是什么意思了。将字典解包到全局命名空间是个坏主意,但将字典解包到函数是好的。