1

我正在用 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 的属性,只是读取它们。如果可能的话,我也对实现高性能感兴趣。

4

2 回答 2

1

通常,当您的程序在不同的地方需要许多参数时,提出一个简洁的配置系统是有意义的,通常是一个为您自己的代码提供特定接口的类。

实例化该类后,您手头就有一个可以传递的配置对象。在某些地方您可能想要填充它,而在其他地方您可能只想使用它。无论如何,这个配置对象将是全局可访问的。如果你的程序是一个 Python 包,那么这个配置机制可能会写在它自己的模块中,你可以从包中的所有其他模块中导入它。

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

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

于 2013-07-18T15:04:19.480 回答
0

为了让Jan-Philip Gehrcke的回答更具形象性,请查看A global class pattern for python(顺便说一句:它只是一个普通的类,“全局”没有什么特别之处 - 但你可以“全局”传递它)。

在我自己的程序中实际实现这一点之前,我有同样的想法,但想知道其他人是如何做到的(比如提问者 nicholls)。一开始我对实现这个有点怀疑,特别是在模块本身中实例化一个类看起来很奇怪。但它工作正常。

但是,有一些事情要记住:

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