【问题标题】:How to deal with global parameters in a scientific Python script如何处理科学 Python 脚本中的全局参数
【发布时间】:2013-07-17 14:37:28
【问题描述】:

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

【问题讨论】:

    标签: python class variables parameter-passing


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      为了让 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。然后,您还可以在加载模块/功能后调整配置类。
      • 当然还有更多问题...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-01
        • 1970-01-01
        • 2011-09-23
        • 1970-01-01
        • 2015-08-29
        • 1970-01-01
        • 1970-01-01
        • 2012-07-24
        相关资源
        最近更新 更多