如何在科学Python脚本中处理全局参数

时间:2013-07-18 14:55:42

标签: python class variables parameter-passing

我正在用Python编写一个科学软件,它包括一个矩形网格上的泊松方程求解器(使用牛顿法)和粒子内部代码。我已将Newton Solver和粒子在单元代码编写为单独的函数,这些函数由我的主脚本调用。

我最初将代码编写为一个大脚本,但决定拆分脚本以使其更加模块化,以便可以单独调用各个函数。我的问题是我有大量的全球"我考虑问题参数的变量。这主要包括问题常数和定义问题几何和网格的参数(如尺寸,某些边界条件的位置,边界条件等)。

主脚本和各个函数都需要这些参数。我的问题是:存储这些变量的最佳方式(也是最合适的)是主要脚本和函数都可以访问它们。

我目前的解决方案是在单独的模块(parameters.py)中定义一个类,如下所示:

class Parameters:
    length = 0.008
    width = 0.0014

    nz = 160
    nr = 28

    dz = length/nz
    dr = width/nr
    ...

在我的主要剧本中,我有:

from parameters import Parameters

par = Parameters()

coeff_a = -2 * (1/par.dr**2 + 1/par.dz**2)
...

这个方法允许我使用par作为我的参数的容器,可以传递给我想要的任何函数。它还提供了一种简单的方法来轻松设置问题空间,使其自己只运行其中一个功能。我唯一担心的是每个函数都不需要存储在par中的所有内容,因此它似乎效率低下一直向前传递。我可以从par中删除许多参数,但是每次调用函数时我都需要重新计算它们,这看起来效率更低。

人们在这些场景中使用的标准解决方案是什么?我应该提一下,我的函数不会改变par的属性,只是阅读它们。如果可能的话,我也有兴趣实现高性能。

2 个答案:

答案 0 :(得分:1)

通常,当你的程序在不同的地方需要很多参数时,有必要建立一个整洁的配置系统,通常是一个为你自己的代码提供某个接口的类。

在实例化该类时,您有一个可以传递的配置对象。在某些地方,您可能想要填充它,在其他地方您可能想要使用它。在任何情况下,此配置对象都可以全局访问。如果您的程序是Python包,那么这个配置机制可能会编写在自己的模块中,您可以从包中的所有其他模块导入。

配置类可能提供有用的功能,例如参数注册(某个代码部分表示需要设置某个参数),默认定义和参数验证。

然后,实际的参数填充基于默认值,用户给定的命令行参数或用户给定的输入文件。

答案 1 :(得分:0)

Jan-Philip Gehrcke 的答案更具象征性,请查看A global class pattern for python(顺便说一下:它只是一个普通的课程,没什么特别的&# 34;全球" - 但你可以传递它"全球")。

在我自己的程序中实际执行此操作之前,我有同样的想法,但想知道别人会怎么做(比如提问者 nicholls )。我首先要对此实现这一点有点怀疑,特别是在模块本身中实例化一个类看起来很奇怪。但它运作正常。

然而,有些事情要记住:

  • 不是超级干净。例如,某个不知道模块中的功能的人不会期望配置类中的参数需要设置
  • 如果必须重新加载模块/函数但希望维护配置类中设置的值,则不应再次实例化配置类:if "mem" not in locals(): mem = Mem()
  • 建议不要将配置类中的参数指定为函数的默认参数。例如function(a, b=mem.defaultB)。 初始化后,您无法更改此默认值。相反,请function(a, b=None): if b is None: b=mem.defaultB。然后,您还可以在加载模块/功能后调整配置类。
  • 当然还有更多问题......