1

我声明了一个类,该类使用定义为类属性的几个硬编码常量进行一些计算。所有方法看起来都类似于以下内容:

class IAPWS_1995:
    @staticmethod
    def dAr_ddelta(delta, tau, Delta, theta, psi):
        _dAr_ddelta = \
            sum(IAPWS_1995.n_0 * IAPWS_1995.d_0 * pow(delta, IAPWS_1995.d_0-1) * pow(tau, IAPWS_1995.t_0)) + \
            sum(IAPWS_1995.n_1 * exp(-pow(delta, IAPWS_1995.c_1)) * (pow(delta, IAPWS_1995.d_1-1) * pow(tau, IAPWS_1995.t_1) * (IAPWS_1995.d_1 - IAPWS_1995.c_1*pow(delta, IAPWS_1995.c_1)))) + \
            sum(IAPWS_1995.n_2 * pow(delta, IAPWS_1995.d_2)*pow(tau, IAPWS_1995.t_2) * exp(-IAPWS_1995.alpha_2*(delta-IAPWS_1995.epsilon_2)**2 - IAPWS_1995.beta_2*(tau-IAPWS_1995.gamma_2)**2) * (IAPWS_1995.d_2/delta - 2*IAPWS_1995.alpha_2*(delta-IAPWS_1995.epsilon_2))) + \
            sum(IAPWS_1995.n_3 * (pow(Delta, IAPWS_1995.b_3)*(psi + delta*IAPWS_1995.dpsi_ddelta(psi, delta)) + IAPWS_1995.dDeltab_ddelta(delta, Delta, theta)*delta*psi))
        return _dAr_ddelta

类范围限定符使代码(甚至更)难以阅读。我曾想过做这样的事情来使代码更具可读性:

...
_ = IAPWS_1995
_dAr_ddelta = \
    sum(_.n_0 * _.d_0 * pow(delta, _.d_0-1) * pow(tau, _.t_0)) + \
...

但是,如果我将常量声明移至模块范围,则根本不需要范围限定符。

是否有理由更喜欢在模块中声明类中的常量(例如,如果我IAPWS_2014将来有类似的类,命名空间冲突?)

4

2 回答 2

1

如果您将来有类似的(可能是现代化的)类,例如IAPWS_2014),考虑使用类方法而不是静态方法是有意义的:

class IAPWS_1995(object):
  n_3 = 123
  ...  # further class data

  @classmethod
  def dAr_ddelta(c, delta, tau, Delta, theta, psi):
    _dAr_ddelta = \
        sum(c.n_0 * c.d_0 * pow(delta, c.d_0-1) * pow(tau, c.t_0)) + \
        sum(c.n_1 * exp(-pow(delta, c.c_1)) * (pow(delta, c.d_1-1) * pow(tau, c.t_1) * (c.d_1 - c.c_1*pow(delta, c.c_1)))) + \
        sum(c.n_2 * pow(delta, c.d_2)*pow(tau, c.t_2) * exp(-c.alpha_2*(delta-c.epsilon_2)**2 - c.beta_2*(tau-c.gamma_2)**2) * (c.d_2/delta - 2*c.alpha_2*(delta-c.epsilon_2))) + \
        sum(c.n_3 * (pow(Delta, c.b_3)*(psi + delta*c.dpsi_ddelta(psi, delta)) + c.dDeltab_ddelta(delta, Delta, theta)*delta*psi))
    return _dAr_ddelta

这样,这个类的较新版本可以继承旧版本,并覆盖实际已更改的变量。如果计算没有改变,则不能重新实现:

class IAPWS_2014(IAPWS_1995):
  n_3 = 1234
  ...

关于您的原始问题的一个更好的副作用是您可以随意命名类的参数。 cls可能是典型的(并且是根据 PEP8 的规范),但也c可以正常工作并与您的_版本一样缩写代码。

于 2013-05-08T19:07:42.697 回答
1

另一种方法是简单地创建一个名为 的模块IAPWS_1995,因为您实际上并没有从该类中实例化对象。您的模块看起来像:

n_0, n_1, n_2, n_3 = ...
d_0, d_1, d_2 = ...
t_0, t_1, t_2 = ...
c_1, = ...
b_3, = ...
alpha_2, beta_2, gamma_2, epsilon_2 = ...
dpsi_ddelta = ...
dDeltab_ddelta = ...

def dAr_ddelta(delta, tau, Delta, theta, psi):
    _dAr_ddelta = (
        sum(n_0 * d_0 * pow(delta, d_0-1) * pow(tau, t_0)) +
        sum(n_1 * exp(-pow(delta, c_1)) * (pow(delta, d_1-1) * pow(tau, t_1) * (d_1 - c_1*pow(delta, c_1)))) +
        sum(n_2 * pow(delta, d_2)*pow(tau, t_2) * exp(-alpha_2*(delta-epsilon_2)**2 - beta_2*(tau-gamma_2)**2) * (d_2/delta - 2*alpha_2*(delta-epsilon_2))) + \
        sum(n_3 * (pow(Delta, b_3)*(psi + delta*dpsi_ddelta(psi, delta)) + dDeltab_ddelta(delta, Delta, theta)*delta*psi)))
        return _dAr_ddelta

常量作为模块级变量,类方法是模块级函数。

其他代码可以像这样使用它:

import IAPW2_1995

x = IAPW2_1995.dAr_ddelta( arg1, arg2, arg3, arg4, arg5 )
于 2013-05-08T19:20:57.133 回答